[email protected]

You've built a cool new web application with Ruby on Rails (or similar framework) and released it to the world. Everything works as expected, but users are starting to complain about the app being too slow. And you're starting to regret following that mantra about "premature optimization."

Improving your web application's performance can be a daunting task, but it's an important factor in keeping users happy and productive. In this article, I present strategies for identifying common performance problems in Rails applications and ways to fix them.

The Strategy

The process of tuning the performance of a Rails app is not much different than any other software framework: Identify your biggest bottlenecks, remove them, and repeat until performance is acceptable. If this sounds familiar, you've probably performance tuned other applications built with another framework. Much of your experience will translate from project to project, framework to framework.

The performance characteristics of a Rails app in a development environment can be very different than a production environment. For example, class caching is enabled by default in production, which means that the code is loaded once and kept in memory until the application is restarted. In development, every class is reloaded on every request, which makes for a shorter feedback cycle to enable rapid, iterative development, but adds some noise to your performance metrics.

To remove this and other variations in performance, emulate the production environment as much as possible. The easiest way to do this is to simply run the application in production mode. If you edit your config/database.yml file and point the "production" environment to your development database, you can use your development database in production mode for profiling:

development: &development adapter: sqlite3 database: db/development.sqlite3 production: <<: *development

When you start your server in production mode, Rails will now use your development database:

$ script/server -e production

You'll just need to remember to restart your server to pick up any code changes because class caching is enabled in production mode.

You might also find that your svelte development database doesn't reflect the real world. To simulate a user's experience in the wild, test with a local copy of your production database (sanitizing sensitive datasocial security numbers, credit-card information, e-mail addresses, and the likeof course).

There's one exception. I use the QueryTrace plug-in for Rails (github.com/github/query_trace) in development mode, but I don't deploy it to production. This plug-in logs the stack trace when each SQL query is logged, which makes it easy to pinpoint the code that's causing the query to be executed. In production it probably impacts performance (ironically undoing some of the progress it enables), so don't add the plug-in to your project's version-control repository.