Thin vs Unicorn on Heroku
Asked Answered
P

3

34

Just wanted to get people's opinions on using Unicorn vs Thin as a rails server. Most of the articles/benchmarks I found online seem very incomplete, so it would nice to have a centralized place to discuss it.

Unicron is a multi-processes server, while thin is an event based/non-blocking server. Event-based servers are great... if your code is asynchronous/non-blocking - vanilla rails is blocking. So unless you use non-blocking rails libraries, I really don't see the advantage of using Thin. Even worse, in a non-blocking server, if your i/o loop is blocking you're going to block the entire loop and not be able to handle any more requests until the blocking call returns. Blocking libraries are going to slow thin down!

Why did Heroku choose Thin as their default server (for cedar)? They are smart guys, so I'm sure they had a reason.

Bellow is a link that suggests replacing Thin with 4 Unicorn workers - this makes perfect sense to me. 4 Unicron workers on Heroku

Petulah answered 21/12, 2012 at 5:3 Comment(1)
Don't really have a full answer to your question. One thing I will not about this is that Unicorn is great for debugging check out the README on github: github.com/defunkt/unicorn#readmeValvular
C
25

Thin is easy to configure - not optimal, but it just works in the Heroku environment.

Unicorn can be more efficient, but it needs to be configured: How many workers? Preload App? What do you pick?

I have released Unicorn Heroku apps with workers set to 3, 5 and 8 - just based on how big each app is - how much code, how much memory is used and how much traffic you get all go into picking this number, and you need to monitor over time to make sure you got the number right, and your app isn't running out of memory.

Preload false - this will make your app start slower, but when Unicorn restarts a worker, this is 'safer' with network connections (memcache, postgres, mongo etc)

Preload true - this is better, but you need to handle server re-connections correctly in the pre and post fork code.

Thin has none of these issues out of the box, but you only get process of execution.

Summary: It's really hard to configure Unicorn out of the box to work well (or at all) for everyone, whereas Thin can just work to get people running with fewer support requests.

Caracas answered 25/12, 2012 at 1:0 Comment(6)
Preload setting effect only the load time on deploy - so it's not a huge deal. Anything else I should watch out for?Petulah
Preload false can push your app over the 30 seconds that Heroku will queue requests during an app deploy. I've had this happen to me, and had to switch back to Preload true - and then you have to know to handle reconnects for e.g. ActiveRecord, Memcache, MongoDB, Redis, NewRelic etc, etcCaracas
Do you know if there is an issue around modifying global variables with Unicorn. I'm wondering if the different workers are all sharing a global namespace or if they are keeping their own global variables. Thanks!Handgrip
what about slow clients? since heroku doesn't use a webserver like nginx in front of unicorn? unicorn.bogomips.org/PHILOSOPHY.htmlElegize
@Brian - the workers are all isolated instances. They share memory that hasn't been touched yet, which with Ruby's current GC, ends up not being much at all.Caracas
Heroku says they don't put nginx in front of apps, but my logs say that they do. I've seen Varnish headers in my application too, and they say they don't do that for Cedar applications.Caracas
F
13

Recently (only a few months ago) the folks behind Phusion Passenger add support to Heroku. Definitely this is an alternative you should try and see if fits your needs.

Is blazing fast even with 1 dyno and the drop in response time is palpable. A simple Passenger Ruby Heroku Demo is hosted on github.

The main benefits that Passengers on Heroku claims are:

  • Static asset acceleration through Nginx - Don't let your Ruby app serve static assets, let Nginx do it for you and offload your app for the really important tasks. Nginx will do a much better job.

  • Multiple worker processes - Instead of running only one worker on a dyno, Phusion Passenger runs multiple worker on a single dyno, thus utilizing its resources to its fullest and giving you more bang for the buck. This approach is similar to Unicorn's. But unlike Unicorn, Phusion Passenger dynamically scales the number of worker processes based on current traffic, thus freeing up resources when they're not necessary.

  • Memory optimizations - Phusion Passenger uses less memory than Thin and Unicorn. It also supports copy-on-write virtual memory in combination with code preloading, thus making your app use even less memory when run on Ruby 2.0.

  • Request/response buffering - The included Nginx buffers requests and responses, thus protecting your app against slow clients (e.g. mobile devices on mobile networks) and improving performance.

  • Out-of-band garbage collection - Ruby's garbage collector is slow, but why bother your visitors with long response times? Fix this by running garbage collection outside of the normal request-response cycle! This concept, first introduced by Unicorn, has been improved upon: Phusion Passenger ensures that only one request at the same time is running out-of-band garbage collection, thus eliminating all the problems Unicorn's out-of-band garbage collection has.

  • JRuby support - Unicorn's a better choice than Thin, but it doesn't support JRuby. Phusion Passenger does.

Hope this helps.

Fathom answered 13/2, 2014 at 4:49 Comment(0)
A
10

Heroku does not use intelligent routing - it will randomly assign jobs to dynos regardless of whether the dyno is busy. Thus, if your dyno cannot handle multiple jobs at once, you will get latency (perhaps massive latency) even if you are paying for lots of other dynos that are free. " That's right — if your app needs 80 dynos with an intelligent router, it needs 4,000 with a random router. " http://news.rapgenius.com/James-somers-herokus-ugly-secret-lyrics

Heroku says they are working on this, and their plan is to make it easier to use Unicorn. They basically said "Oops, we didn't notice that this was a problem for a few years... and now that we look, it's definitely a problem for Thin... so I guess you need to use a different program than the one we've been pushing all this time." http://news.rapgenius.com/Jesper-joergensen-routing-performance-update-lyrics

From the official Heroku explanation (second link above): "Rails, in fact, does not yet reliably support concurrent request handling. This leaves Rails developers unable to leverage the additional concurrency capabilities offered by the Cedar stack, unless they move to a concurrent web server like Puma or Unicorn.

Rails apps deployed to Cedar with Thin can rather quickly end up with request queuing problems. Because the Cedar router no longer does any queuing on behalf of the app, requests queued at the dyno must wait until the single Rails process works its way through the queue. Many customers have run into this issue and we failed to take action and provide them with a better approach to deploying Rails apps on Cedar."

Also of interest is that their performance tools, including New Relic, have not been reporting time spent in the dyno queue. http://news.rapgenius.com/Lemon-money-trees-rap-genius-response-to-heroku-lyrics

Oops.

Asgard answered 13/11, 2013 at 22:41 Comment(2)
Thank you for the rapgenius article- pretty stunning/disappointing to learn about such a massive fail and misrepresentation by Heroku. Guess the take away is: you'd better milk Unicorn's multiple processes for concurrency, because Heroku's dyno-level concurrency is a sham.Incessant
This is where running a clustered app server like Torquebox can really reap some benefits. If you've got an app with a high level of traffic, get off of Heroku and deploy 3 clustered Torquebox app servers. Intelligent load balancing of web and background processes, rolling deployments, clustered memcached and queueing built it. It's a stack in a box.Inbreathe

© 2022 - 2024 — McMap. All rights reserved.