Main image of article Scaling Ruby on Rails: Practical Advice
It’s the problem everyone wants to have — the need for scalability due to an influx of users and clients compared with what you expected when you launched your application or website. Ruby On Rails LogoLessAccounting’s Steven Bristol is familiar with the problem. As the business bookkeeping system for entrepreneurs increased in popularity, the company worked to increase its servers’ ability to process an increasing number of requests. Although Bristol believes that scaling in Ruby on Rails is similar to other frameworks, Andrew Wicklander, founder of the software company Ideal Project Group, points out that several factors make scaling in Rails accessible to people with a variety of skillsets. “One of the benefits that Rails offers is that it has a huge community around it, and there are a lot of tools, so that you don’t have to be an infrastructure expert in order to scale your web apps,” Wicklander says. “There are tools that exist that allow you to scale Rails apps without having to know a lot about the infrastructure. It’s easy to scale on Rails because infrastructure is now sold as a service. You can scale without necessarily having to get deep into your code and modifying a whole lot of things.” Rails.MN organizer and Zipnosis Lead Developer Derek Rockwell points out that Ruby isn’t the best tool for all applications. “Ruby is an interpreted language with a lack of true support for multithreading until future versions, which can be problematic for CPU intensive applications, where other implementations of Ruby (such as JRuby), or even other languages may make more sense,” he explains. However, he notes, “Rails interfaces well with a lot of tools — caching servers, profiling tools and analysis tools that make it a whole lot easer to do initial scaling.”

Locating the Bottleneck

The first step to improve responsiveness for the end user is to figure out what’s causing the slowness by doing some performance profiling. Isolating the one part or aspect of the site that is slow is the first step, but oftentimes that’s not immediately obvious. If it appears that the whole site is slow, the next step is to determine what’s causing the problem. “If the whole website is slow, then you’re looking at general things, like is the server capacity too slow? Is it database access? Is it the database itself? Is it an I/O problem, either not enough memory or not enough CPU to handle the load?” Bristol explains. Looking through the Rails log or using New Relic is a good way to pinpoint specific issues and isolate the problem, which then allows you to make adjustments to improve performance. Adding a bigger server if it’s a hardware issue is an easy step, but isolated problems may require a bit more sleuthing to determine what the actual bottleneck is.

Improving Performance

Many problems that arise have easy solutions. “Caching is a no-brainer,” Rockwell explains, pointing out that database queries that take too long may have to do with something as simple as a missing index. “There’s low-hanging fruit you can address to make improvements,” he says, and addressing them will improve site performance and save money as well. “If you take 15 percent off your response time and your theoretical maximum page visits increases by 15 percent, that can take care of the problem without you having to buy a whole new server or up your cloud storage.” Bristol points out that slow database queries can be optimized as well. “You can break it into several queries, or change the way the page works so you don’t need the whole page at once, or put in some caching so the next time they load it, the page loads quickly from that cache.” You can add caching solutions like Redis or Memcache to your Rails application. However, the latter has its limitations. “Memcache has a hard limit on the amount of memory it will allow for total cache store. If you get over that limit, you need to recompile memcache,” Bristol explains. So LessAccounting uses Will Cache, a caching gem written by their developer Dejan Simic. It allows users to employ the same kind of Rails interface for caching, regardless of what objects they’re using it against. Caching, proper indexing and removing n+1 queries (gems like Bullet will help you analyze database queries and pinpoint out the biggest offenders) should help you address any thoroughput problems. TurboLinks, a gem that will be included by default in Rails 4, was created by 37signals partner and Ruby on Rails creator David Heinemer Hanson (DHH) himself. “DHH realized that a considerable amount of time on Basecamp was spent reprocessing and re-rendering Javascript and CSS on the pages, and that didn’t make any sense because they’re all using the same JS and CSS, so basically you make an Ajax call that reloads all of the content on the page, without reprocessing the CSS and JS and all that. TurboLinks creates a 20 to 70 percent responsiveness increase,” Rockwell says. Other tools he uses include Web traffic caching reverse proxy Varnish partnered with a CDN. “One of the biggest pieces of scaling is to avoid hitting your application tools if you don’t need to, which sounds obvious, but if I have a homepage and About Us page, I don’t ever need to touch Ruby on Rails for those pages. Services like Varnish partnered with a CDN will load up your homepage once, and it’ll be cached until it changes. This works well with static pages, and services such as Varnish and Cloudplayer can do that really well.”