Skip to content

Instantly share code, notes, and snippets.

@dominic
Created April 7, 2013 05:41
Show Gist options
  • Save dominic/5329193 to your computer and use it in GitHub Desktop.
Save dominic/5329193 to your computer and use it in GitHub Desktop.

Replying to a Twitter conversation with @johnjoseph_code:


Our number one concern is helping our developers get better performance out of their app. Period.

We are recommending Unicorn so that developers will use more RAM. Most Rails apps that I examined were using thin - because we had recommended it in the past - and were not using anywhere near the full capacity of their dynos in terms of memory or CPU. Because of Unicorn's forking process model, it is often a trivial switch for an application to make that provides a near instant boost in performance for them by actually using all the RAM they have requested. With 2X dynos, developers can verically scale pretty well, generally fitting 4-8 unicorn workers on a dyno (or more if you set extremely tight conditions with https://github.com/kzk/unicorn-worker-killer).

We hope developers switching to Unicorn and 2X dynos will be able to scale down their apps from where they are today. You are correct that we sell in units of RAM (though in reality it is a container with an allocation of RAM and a share of CPU, IO, etc - 2X dynos have twice the sahre of CPU, for instance). And we hope Unicorn will let them use more of the resources they are paying for today.

As for Puma and Thin - both are great servers! However, both are almost guaranteed to require changes in the way the application is structured to fully utilize their potential. We were simply not willing to say today "Hey, we see you're having performance problems on Heroku. Go rewrite your app and you'll be fine". In general, I think an app built to properly harness the power of either of these servers is very likely to exceed the performance of the same app on Unicorn. Definitely taking your feedback to heart here. We can do a better job providing a recommendation. I'll start thinking about how we might best document the benefits and pitfalls associated with each server for our developers in a way that allows them to make a more informed choice when they a just starting to developer their application.

As for blocking IO, this is a definite Unicorn problem. In general, it will not impact most normal HTTP requests because we buffer 8K of headers and request body (https://devcenter.heroku.com/articles/http-routing#request-buffering). That's not good enough though. File uploads on Unicorn just plain suck without something in front of it to buffer the full request. We're considering lots of options here, including some zany things like deploying nginx in front of all apps at the dyno level (which would be pretty neat!), as well as investigating Rainbows!, which I wasn't aware of until recently. Given the relative obscurity of Rainbows! though, I am hesitant to recommend it without a lot more testing (the warnings on the homepage especially give me great pause). We do have some new internal clients on Zbatery (a Rainbows! offshoot), and it definitely looks promising.

I have not seen the email you mentioned, but I agree - it sounds sloppy. We have tried to be extremely careful not to miscommunicate our advice, but performance is just a tricky subject to make sweeping recommendations about. Would you mind forwarding the message to dominic [at] heroku ?

@jjb
Copy link

jjb commented Apr 8, 2013

also, ruby 2.0, which has CoW, should be suggested

@dominic
Copy link
Author

dominic commented Apr 9, 2013

Cool - definitely agree on all those points. Here's the basic list of things I want work on based on your initial response to the email and your feedback here:

  1. Survey of Ruby application servers. Build out the pros, cons and unique behaviors of each of these options. We should do the most we can to educate developers who are starting new apps, and help those having trouble with performance or scaling choose the technology that best fits their needs.

    Additionally, I'd like to provide additional metrics surrounding each of these servers in our docs. Though Unicorn scales linearly in memory, it's impact on routing is significantly greater than that. RG scratched the surface modeling it with two workers here. To use your words - Unicorn is better at scheduling a queue than Heroku's router, and that's because it is a global queue. At that small scale, the problem for Unicorn's queueing is trivial, and it works marvelously. Increasing the number of workers available on each dyno only makes performance better. I'd like to build and share the graphs to prove it :)

  2. Document file upload suggestions. I just learned something super interesting about this today that I'd like to document and recommend further. Discussing this today with colleagues, @ryandotsmith pointed me to S3 upload support. Rather than uploading files first to the dyno and then to a asset service, one can simply POST their files directly to S3. I'd argue any day that our dynos can be doing better things for you than serving files, so I'm really excited to pursue this. It's been well documented here and available in gem form here.

    I'll be adding this caveat to our Unicorn docs and suggesting an approach similar to S3 direct uploads for handling files going forward.

  3. Ruby 2.0.0 and CoW. This is something I've been meaning to revisit. In our early tests during this incident response, Ruby 2.0.0 actually consumed slightly more memory over time with Unicorn. This result was obviously counter-intuitive (and, I assume, a fluke), so we set it aside to revisit it again with clearer heads. Now would be a great time to revisit it! I'm using Ruby 2.0.0 on all new apps in Heroku and in my personal development, and I see no reason not to recommend it to users. @hone is our Ruby expert though - I'll ask him if there are any blockers in his mind for making that the default.

I'm a little sleepy, so let me know if I missed anything!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment