Performance is often ignored in Rails development until it becomes a problem. If ignored too long, though, it can get very tricky to improve. It’s valuable to regularly audit performance and look for hotspots or design choices that are slowing things down.
Inspecting the Logs
Inspecting the log will help identify the source of several performance issues the application may have.
The Rails application log outputs the time spent processing each request. It breaks down the time spent at the database level as well processing the view code. In development mode, the logs are displayed on STDOUT where the server is being run. In a production setting the logs will be in
log/production.log within the application’s root directory.
Take note of lines 4-9 in the following request:
1 2 3 4 5 6 7 8 9
- Lines 4-7 include a breakdown of the time spent executing the database queries to fulfill the request.
- Line 8 indicates how long was spent building the view
- Line 9 reports the total time spent along with a breakdown of time in the view vs in the database
The total time will likely be greater than the sum of the view and database processing time. The remaining time is spent in other parts of the system, such as the router, controller, and logger I/O.
NOTE: Be aware of the environment of the log being inspected. By default, in production the log output will not include the details of time spent processing each database query, although it will still provide the total time as indicated on line 9 of the above request. Lines 4-7 of the above request would not be present in production.
Response time for an effective application should never go above half a second. If you cross that line, it’s time to investigate ways to move some of the processing to asynchronous workers, cut down the number of queries, or cache data.
If the log for a single request is filled with a lot of database queries that can often be a red flag in identifying a performance bug. A normal request should have somewhere between 1-4 queries. If more than that are being spawned, they should be condensed using techniques in the Query Strategies section.
New Relic (http://newrelic.com) is an essential tool for any Rails application. It tracks the performance of every request and can be used in both development and production.
newrelic_rpm gem to your
Register for an account at http://newrelic.com/ and get the
newrelic.yml from the welcome email. Drop this file into the
/config directory of your project.
Usage in Development
New Relic will track the most recent 100 requests in development. To view the data visit
/newrelic in your browser.
So, assuming your app is running on
localhost:3000, find New Relic at
Usage in Production
There’s no additional configuration for production, just run your app as normal then view the results under your account at http://rpm.newrelic.com/
PerfTools.rb is a port of Google’s Perftools: https://github.com/tmm1/perftools.rb
It’s an amazing library to profile which methods are making up the bulk of your processing time.
Basic Ruby Usage
Using a block:
1 2 3 4
1 2 3 4
my_app.rb is the external file
With the data file generated you can create a variety of reports.
Plain Text Table
The simplest is the plain text table. Run this from the command line:
Where the columns indicate:
- Number of profiling samples in this function
- Percentage of profiling samples in this function
- Percentage of profiling samples in the functions printed so far
- Number of profiling samples in this function and methods it calls
- Percentage of profiling samples in this function and methods it calls
- Function name
In a typical Ruby/Rails application, columns 4 and 5 are the most interesting. The methods you write usually aren’t CPU intensive, but they trigger other methods that soak up the CPU. High numbers in 4 and 5 show your methods that are causing the issues.
Even better than the table, Perftools can generate PDFs. You’ll need the
On OS X, install it with
brew install ghostscript.
On Linux, install it with
apt-get install ps2pdf. If you get an error that
ps2pdf package can not be found, try typing
ps2pdf to see if it is already installed as part of the OS.
Then generate and open the pdf with:
Usage with Rails
There’s a Rack middleware which can easily inject PerfTools into your application.
Setting up the Gem / Middleware
First, add the following to your
bundle to install it. Next, open
/config/application.rb and initialize the middleware:
Finally, it’s time to make your request. Enter the URL you want to examine and add the parameter
?profile=true in your browser.
For instance, to see the graph for the
articles#index you could visit:
For better statistical accuracy, you might want to run the same request several times by adding the
- PerfTools.rb: https://github.com/tmm1/perftools.rb
- Google’s PProf: http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html#pprof
- Notes on Profiling Ruby: http://www.igvita.com/2009/06/13/profiling-ruby-with-googles-perftools/
- Rack PerfTools Middleware: https://github.com/bhb/rack-perftools_profiler