Rails, bandwidth, and HTTP content encoding

After moving from Dreamhost to HostingRails I noticed my bandwidth had gone up. On Dreamhost, I was averaging 40GB per month, and on HostingRails, I was averaging 60GB/month. This was a problem because I had bought the 50GB per month plan on HostingRails, and had to either pay extra or let the site go down for the last few days of the month.

I had a few theories as to why my bandwidth had gone up.

  • I had used up a lot of bandwidth moving the data to the new site. The second month’s bandwidth was also high, so that wasn’t it.
  • The more reliable server meant more people were using the site. After checking the stats, this wasn’t the case.
  • Someone was repeatedly pulling some feeds that had no size limit. These feeds could get up to 1MB in size. After adding a limit to the size of these feeds, the problems continued.

I started looking at using HTTP content encoding to get my bandwidth down. The browser tells the server what kinds of encoding it understands, the server responds by encoding (compressing) the content in a suitable format and sending it to the browser. Net result: less bandwidth, more processing for the server and client.

Anyway, I realized that Dreamhost does have HTTP encoding by default, and HostingRails doesn’t. After a quick search through the HostingRails forum, I found that they indeed don’t have it on, but they also don’t grant requests to have it turned on in Apache.

Having it turned on in Apache is ideal because then it’ll affect static content as well, but there are ways to do it in Rails (and probably other languages, but I only care about Rails). Courtesy Tom Fakes, here are short and sweet instructions.

  1. Pick a page on your site and use Live HTTP Headers to see the size of the downloaded file. Look for Content-Length in the response; this is how many bytes had to be transferred across the network to download the page. While you’re there, check for Content-Encoding. If you see it, congratulations (or condolences), you’re already compressing your output.
  2. Put compress.rb in your app’s lib directory.
  3. In app/controllers/applications.rb, add require 'compress.rb' at the start and after_filter OutputCompressionFilter after the start of the class. See update below.
  4. Restart Rails, and check Content-Length of the page again.

Result for me: 1/3 lower bandwidth.

Update, Nov 17 2007: I discovered that turning on compression in ApplicationController causes problems if you’re using page caching. The compression filter happens before the caching filter, so the compressed form gets cached. When the page is retrieved from cache, it doesn’t get sent with the proper headers. The solution to this is to add the after_filter line to each individual controller after the caches_page lines you use. This will make the caching happen first.

2 Responses to “Rails, bandwidth, and HTTP content encoding”

  1. Alex Bischoff Says:

    Just a minor typo in step 3 — the file you link to is “compress.rb”, but the link text is for “compress.js”. No biggie, but I just thought I’d let you know.

  2. Jason Barnabe Says:

    Thanks Alex, I’ve fixed it.

Leave a Reply

Adventures in development - Web standards and Firefox extensions