Skip to main content

Setting Up a Cloudfront CDN for Rails

Setting Up a Cloudfront CDN for Rails?

Implementing a CDN to serve compiled assets in Rails is one of the most significant performance enhancements I’ve seen. Having done so for 2 fairly large applications, it’s hard for me to imagine serving assets locally anymore.
The Asset Pipeline

The addition of the Rails asset pipeline has reduced both the number of assets served and the size of these files. Users on slow connections have been the biggest beneficiary of these changes.
The Problem

Even with the asset pipeline, content is transmitted to the end user over their, sometimes slow, connection. Distance plays a role in the speed at which data can be delivered. Because of this, users further away from your servers get a sluggish experience. This decreases both the users’ patience and your ability to effectively engage them.
The Solution

CDNs are networks of servers that host your content so that when you make a request, the request is served from a server closest to you. This can often reduce transmission time by several seconds (…think users in Asia requesting content that’s served from Virginia – this is the case if you deploy to Heroku).

The use of a CDN also reduces the number of requests to your application servers. Most Ruby applications use Nginx or Apache in front of the Ruby processes. These HTTP servers are really good at serving static content, but no one will deny – the fewer requests, the better.
Option 1: Push your assets to the CDN during deployment

Depending on your method of deployment, pushing assets to a CDN isn’t always trivial. The asset_sync gem has made this relatively straight forward if you choose to host your assets from Amazon S3. Out of the 2 options, this is the most efficient because all requests for assets will be diverted away from your application, leaving its precious processing power to serve more important application requests.
Option 2: Assets are pulled to the CDN on first request

This option won’t change deployment and is simple to setup. The only downside is that upon first request to an asset, the CDN will pull it from your web server and cache it (it’s hardly a downside if you’re currently serving all your assets from your web server). All subsequent requests to that asset will be served straight from the CDN. The simplicity of this option generally makes it my preferred option.

So let’s get to it…
Amazon Cloudfront

Log in to your Amazon EC2 account and click “Cloudfront”:

"Click Cloudfront in the AWS web console"

Click “Create Distribution”:

"Create a Cloudfront distribution endpoint"

Enter the domain where your assets currently live (ignore Origin ID – it’ll be filled in for you):

"Settings for a typical CDN"

Make note of the Cloudfront distribution URL

"Cloudfront distribution URL"
Rails

Rails provides and easy way to change the host URL of the assets (images, stylesheets, javascripts, fonts…). Enter the Cloudfront distribution URL from above as the Rails asset_host.

# config/environments/production.rb
config.action_controller.asset_host = "d24xjtg100euk4.cloudfront.net"

At this point, the domain of all Rails asset helpers image_tag, stylesheet_link_tag, and javascript_include_tag will be prefaced with the asset host URL that you configured above.

For example:

image_tag("shark_teeth.png")
# http://d24xjtg100euk4.cloudfront.net/assets/images/shark_teeth.png

Note: if you only change config/environments/production.rb, you won’t see any changes in your development environment.

And that’s it!
In Summary

This is the ultimate low-hanging fruit optimization. If you haven’t served your assets from a CDN before, I’d suggest giving it a try. The cost of Cloudfront is minimal, and in my mind, worth 10x that.

I’ve recently been trying out a service called Fastly, which is an alternative to Cloudfront. It’s slightly more expensive, but seems to have better and more consistent performance.


Comments

Popular posts from this blog

Error malloc(): memory corruption nginx with passenger?

Error malloc(): memory corruption nginx with passenger Passenger issue resolving steps :  sudo gem uninstall passenger(uninstall all passenger) sudo gem install passenger sudo passenger-install-nginx-module --auto --auto-download --prefix=/opt/nginx --extra-configure-flags=none Update nginx config file with new passenger version and restart the nginx

Lazy loading in rails – Rails Feature

 Lazy loading in rails – Rails Feature ? Lazy loading in rails is the amazing feature provided with rails. In console you might have tried to examine how lazy loading in rails actually works. In this tutorial, we will learn about this Rails - Lazy loading feature with examples. What exactly is Lazy Loading? As the name suggests the data is loaded in lazy manner (Really!) i.e. Your database is queried only when data from the database is required for some kind of manipulation in code. You will get more of this after you read how-to of lazy loading below. How lazy loading works: Whenever you try to get some data from database, For example, users is the database table that you have. And you are querying database to get users having age less than 20. Then, you will write code like, result = User.where("age < 20") when above statement is executed, your database is not queries yet(because the resultant data is not required yet). When you execute following code, records = resu...

Rails Migration Difference between Text and String

Rails Migration Difference between Text and String ? While working with Rails Migration Difference between Text and String is important to be known to every developer. Columns and their data types are finalized while deciding Table structure. This tutorial will help understand difference between String and Text column type and illustrate how to write Rails Migration implementing the same. You might want to read about database.yml files for specifying database configuration for Rails Application. 1. Concepts When String or Text data type is required?     Whenever you require your column to store information which is lengthy in size (Many characters), you need to consider String or Text data type for the column.     Both of them let you store Many(How Many - will see later) characters Difference between String and Text Considering MySQL database Feature     String     Text Length     1 to 255     ...