Speed up your Apache/Passenger Rails app in 2min

Posted by Trevor in Ruby/Rails on June 11, 2009

Here's a quick tip for speeding up your Apache/Passenger powered Rails app. It'll take you about 2 minutes, and I guarantee you'll notice the speed-up.

  • SSH onto your VPS
  • Run the following commands: "a2enmod expires" and "a2enmod deflate"

Now, open up your Apache vhost config for your Rails app. Add the following:

Then, restart Apache by running: "/etc/init.d/apache2 restart"

This will gzip your html, css, and javascript. It'll also add far future expires headers for the appropriate cacheable filetypes. There's no downside, and it only takes a second. Bang for buck.

Edit: Check the comments for some possible downsides... ;)

12 Comments

That’ll keep your assets cached forever in browsers and caches. New versions of those files will never be retrieved by clients unless they hard refresh or clear their cache. I’d suggest using Rails-style asset timestamps (“/foo.png?82349824984″) and only set the expires/max-age headers if an asset timestamp is present. Great tip, though. Most sites will see a huge improvement.

 Trevor

Hmm… yeah, I hadn’t thought of the impact on chrome and whatnot. I’ll make a note in the post and reconsider the approach. I’m using the Rails-style asset timestamps, though. Wouldn’t that take care of the cache busting?

I doubt you’re using those asset timestamps in your CSS when referencing images used in the interface. File matching regex should probably be changed to only match if asset timestamp is present, just like Ryan Tomayko said.

 Trevor

Yeah, I guess not. Any chance of getting some pointers on how to fix this?

This would do the trick wouldn’t it:

# gzip html, css and js
AddOutputFilterByType DEFLATE text/html text/css application/x-javascript application/javascript

# far future expires headers
<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)?d{10}$">
ExpiresDefault "access plus 10 years"
</FilesMatch>

 Trevor

Thanks, Josh! I’ll give that a try. Seems like it would work well to me.

 Brad

Good tip, don’t forget to mention you need to enable mod_deflate also: a2enmod deflate in order for the gzipping to work.

Also, the a2enmod scripts are debian specific i believe? other [lame] distros might need to manually add the module.

And, couldn’t get josh’s code to work, kept saying my css files didn’t have expires headers

 Erik

After trying a few variations I found I needed to add

ExpiresActive on

to get the Expires headers working. Though I still cannot get the regexp for the timestamps to work. I have tried a few variations that work in Perl/Ruby but I get no results in Apache.

Anyone have a working example that handles timestamps?

Regards

Erik

 Mike

If this was possible, I think the ‘?’ and ‘d’ in that regex would need to be escaped as follows:

I believe, however, that it will not work. I tried this a number of different ways and it appears that the Apache directive ignores the ‘?’ and everything that follows. Otherwise, how could ‘myimage.jpg?1234567890′ possibly match a regexp ending in “$” (which means string ends here)? I did some tests and this is in fact the case–timestamped assets are matched by the original regex and fail to match with any additions after the file extension.

 Mike

Oops, comment editor swallowed my example code–must not like angle brackets. My example just added a backslash before the ‘?’ and ‘d’ in the regexp.

[...] two configuartion tweeks are, I believe, the rough equivalent of the technique previously discussed on this blog for [...]

 Paul

I think you’re right Mike, FilesMatch doesn’t match against the query string.

I’ve been using ERB to render my stylesheets so that they do include time stamps, I wrote about it here: http://deaddeadgood.com/2009/9/28/far-future-expires-headers-for-css-images-in-rails

Leave a comment

WP_Big_City