Ruby on Rails
HowtoScale (Version #16)

Scaling

Ruby on rails is often criticized for scaling poorly. However it is possible to scale and its really not that complicated.

Some tips:
analyze analyze analyze. Find a way to measure where the bottleneck is. Do you need more mongrel processes? Is the DB slow?

A common solution is to use nginx+memcache+a large db box.

One way to improve performance is to engineer your application (and info architecture) so that you have lots of pages with unique url’s that are suited towards page caching. While most pages can never be compressed down to be completely static, it’s possible to cache “most” of a page and still use Rails page caches. Here’s an article that has some information and links on using Nginx, SSI and Rails page cache to radically improve Rails performance:

http://www.misuse.org/science/2008/02/22/rails-page-caching-nginx-ssi-ajax-and-form-posts/

Twitter is probably the biggest ruby on rails app at the moment and they have a presentation at http://www.slideshare.net/Blaine/scaling-twitter/ although it probably isn’t as good as the more informative http://www.slideshare.net/Georgio_1999/how-to-scale-your-web-app/

http://www.scribd.com/doc/49575/Scaling-Rails-Presentation covers figures of scaling and monitoring solutions

http://railsexpress.de/blog/ has some excellent plugins to improve rails performance

And finally: Cache, cache, cache.

Some other ‘tweaks’ that might affect performance:
make sure ruby is compiled with pthreads turned off.
Investigate into using evented_mongrel instead of normal mongrel.
Optimize the database (lots of indices).

Analyze.

http://blog.caboo.se/articles/2007/7/29/scale-rails-from-one-box-to-three-four-and-five
tune DB

make sure not have a ruby compiled with -pthreads, and you have the latest patch version
install and require the fast thread library (may have slightly more updated thread code). Will if you’re using 1.8.6 patch level 0.

can have nginx mem cache small files (!) http://www.pivotalblabs.com/articles/tag/standup

It should be 4-10x slower (for processing) than django. DB same speed obviously :)

Add mongrels till CPU is at about 100% (?) or you run out of RAM. If you bottle neck isn’t RAM then maybe set the GC to start only every so often.

jruby might (by now) be slightly faster than normal ruby.

http://www.webficient.com/2007/08/testing-various-configurations-of-rails.html notes there is a more efficient logger out there—analogger, and compares merb/rails+evented mongrel/swiftiplied mongrel behind nginx.

tweak evented_mongrel have it use epoll (from http://rubyforge.org/pipermail/eventmachine-talk/2007-August.txt)

http://www.juixe.com/techknow/index.php/2007/02/28/rails-performance-link-fest/
has some good rails optimization links

http://blog.pluron.com/2008/01/ruby-on-rails-i.html
links some rails code optimization hacks.

http://revolutiononrails.blogspot.com/2007/08/advanced-rails-caching-on-edge.html looks awesome with regard to caching and rails. You have the web server cache the cacheable parts of the page (kind of like moving the partial view caches to the web server). That could be good.

You also need to get some performance metrics to understand how your application performs. For example if your application has a wide range of response times for different actions, you might be well served to use the nginx “fair proxy” balancer which will distribute requests to your Rails app only when the rails app is available for work. So fast requests won’t get stuck behind slow requests. There’s some performance testing info on this subject here:

http://www.misuse.org/science/2008/04/07/thin-ruby-on-rails-nginx-fair-proxy-performance-testing/

You also want to pick a fast application server. Many people use Mongrel, lighttpd or Thin. This article compares Mongrel and Thin, and also has links to other sources with more testing info:

http://www.misuse.org/science/2008/04/07/thin-vs-mongrel-a-ruby-on-rails-performance-shootout/

Scaling

Ruby on rails is often criticized for scaling poorly. However it is possible to scale and its really not that complicated.

Some tips:
analyze analyze analyze. Find a way to measure where the bottleneck is. Do you need more mongrel processes? Is the DB slow?

A common solution is to use nginx+memcache+a large db box.

One way to improve performance is to engineer your application (and info architecture) so that you have lots of pages with unique url’s that are suited towards page caching. While most pages can never be compressed down to be completely static, it’s possible to cache “most” of a page and still use Rails page caches. Here’s an article that has some information and links on using Nginx, SSI and Rails page cache to radically improve Rails performance:

http://www.misuse.org/science/2008/02/22/rails-page-caching-nginx-ssi-ajax-and-form-posts/

Twitter is probably the biggest ruby on rails app at the moment and they have a presentation at http://www.slideshare.net/Blaine/scaling-twitter/ although it probably isn’t as good as the more informative http://www.slideshare.net/Georgio_1999/how-to-scale-your-web-app/

http://www.scribd.com/doc/49575/Scaling-Rails-Presentation covers figures of scaling and monitoring solutions

http://railsexpress.de/blog/ has some excellent plugins to improve rails performance

And finally: Cache, cache, cache.

Some other ‘tweaks’ that might affect performance:
make sure ruby is compiled with pthreads turned off.
Investigate into using evented_mongrel instead of normal mongrel.
Optimize the database (lots of indices).

Analyze.

http://blog.caboo.se/articles/2007/7/29/scale-rails-from-one-box-to-three-four-and-five
tune DB

make sure not have a ruby compiled with -pthreads, and you have the latest patch version
install and require the fast thread library (may have slightly more updated thread code). Will if you’re using 1.8.6 patch level 0.

can have nginx mem cache small files (!) http://www.pivotalblabs.com/articles/tag/standup

It should be 4-10x slower (for processing) than django. DB same speed obviously :)

Add mongrels till CPU is at about 100% (?) or you run out of RAM. If you bottle neck isn’t RAM then maybe set the GC to start only every so often.

jruby might (by now) be slightly faster than normal ruby.

http://www.webficient.com/2007/08/testing-various-configurations-of-rails.html notes there is a more efficient logger out there—analogger, and compares merb/rails+evented mongrel/swiftiplied mongrel behind nginx.

tweak evented_mongrel have it use epoll (from http://rubyforge.org/pipermail/eventmachine-talk/2007-August.txt)

http://www.juixe.com/techknow/index.php/2007/02/28/rails-performance-link-fest/
has some good rails optimization links

http://blog.pluron.com/2008/01/ruby-on-rails-i.html
links some rails code optimization hacks.

http://revolutiononrails.blogspot.com/2007/08/advanced-rails-caching-on-edge.html looks awesome with regard to caching and rails. You have the web server cache the cacheable parts of the page (kind of like moving the partial view caches to the web server). That could be good.

You also need to get some performance metrics to understand how your application performs. For example if your application has a wide range of response times for different actions, you might be well served to use the nginx “fair proxy” balancer which will distribute requests to your Rails app only when the rails app is available for work. So fast requests won’t get stuck behind slow requests. There’s some performance testing info on this subject here:

http://www.misuse.org/science/2008/04/07/thin-ruby-on-rails-nginx-fair-proxy-performance-testing/

You also want to pick a fast application server. Many people use Mongrel, lighttpd or Thin. This article compares Mongrel and Thin, and also has links to other sources with more testing info:

http://www.misuse.org/science/2008/04/07/thin-vs-mongrel-a-ruby-on-rails-performance-shootout/