www.hward.com Open in urlscan Pro
34.124.149.177  Public Scan

Submitted URL: http://t.co/lIkeLWDPZg
Effective URL: https://www.hward.com/scale-rails-with-varnish-http-caching-layer/
Submission: On September 19 via manual from AU — Scanned from AU

Form analysis 0 forms found in the DOM

Text Content

SCALE RAILS

rails, fastly, cache

An HTTP caching layer can be used to dramatically speed up requests to our web
applications. We’ll walk through setting up a Ruby on Rails application to
return cacheable responses.




VARNISH THE APPLICATION ACCELERATOR

We’ll use Varnish Cache as our HTTP Caching Layer. Instead of hosting our own
Varnish instance, we’ll use a hosted solution provided by Fastly.

When a cache miss occurs, Fastly will fetch the content from our Rails
application and cache it locally before returning the response to the user.



When a cache hit occurs, the response is returned directly to the user (the
Rails application never sees the request).




CACHE-CONTROL HEADERS FOR STATIC CONTENT

The Asset Pipeline allows us to combine and minimize our JavaScript and CSS
files. When using the digests for unique asset URLs we can safely cache the
files for long periods of time.

We’ll set up our production environment to return a max-age of one year on our
static assets.

# config/environments/production.rb
config.static_cache_control = "public, max-age=#{1.year.to_i}"



CACHE-CONTROL HEADERS FOR DYNAMIC CONTENT

The default behavior of a Rails app is to set Cache-Control to private and
return a session cookie.

HTTP/1.1 200 OK Cache-Control: max-age=0, private, must-revalidate Set-Cookie: _hward_session=[REMOVED_DIGEST]; path=/; HttpOnly


We can manually remove the cookie from response header, and override the default
Cache-Control header. Setting the `Cache-Control` to `no-cache` will tell the
browser not to cache the response locally, but will indicate to Fastly its OK to
cache the page on their servers.

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # ...

  private

  def set_cache_control_headers(max_age = 1.year.to_s)
    # removes session data
    request.session_options[:skip] = true
    response.headers['Surrogate-Control'] = "max-age=#{max_age}"
    response.headers['Cache-Control'] = 'public, no-cache'
  end
end


Next we’ll call the `set_cache_control_headers` from a `before_filter` on
publicly accessible pages.

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  before_filter :set_cache_control_headers, only: [:index, :show]
end


HTTP/1.1 200 OK Cache-Control: 'public, no-cache' Surrogate-Control: 'max-age=31557600'


Setting the Surrogate-Control header will indicate to Fastly that the page
should be cached on Fastly servers (but not on the requesting client).


PURGING CACHE

Now that we have our content cached we need to create a mechanism for purging
the cache when a page changes. See Varnish Cache Invalidation with Fastly
Surrogate Keys for more details.

Harlow at Clearbit

Twitter icon GitHub icon LinkedIn icon

Continue Reading

 * Personalization at Edge
 * Geo Caching
 * Microservices
 * War Chest
 * Kinesis Consumer
 * Golang gRPC Context