Search code examples
ruby-on-railscachinghttp-headersherokucache-control

Cache-Control Headers and Heroku Dynamic Images


I'm trying to understand HTTP Caching on Heroku. After reading their article, I'm curious about how the Cache-Control HTTP header is working.

In the sample application mentioned in the article the header is set in a controller action:

def image
    @qrimage = QRImage.find_by_md5(params[:md5])
    if @qrimage
      headers['Cache-Control'] = 'public; max-age=2592000' # cache image for a month
      send_data @qrimage.data, :filename => @qrimage.filename, :disposition => 'inline', :type => "image/png"
    else
      render :nothing => true, :status => 404
    end
end

The code for @qrimage.data is like:

  def data
    qrcode = RQRCode::QRCode.new(self.message, :size => self.version, :level => self.ecc.to_sym)
    qrcode.to_s
  end

So to me it looks like the image is being generated on the server every time. And then cached by the browser for a month. So the only savings here is when the same visitor tries to view the same image.

If different visitors try to view the same image, it will still be generated and sent. Not really all that helpful if you ask me.

Is my understanding correct, or will the same image not be regenerate for each site visitor?


Solution

  • Heroku apps on the Aspen and Bamboo stacks are fronted by Varnish, an HTTP accelerator. Varnish will cache output from your application according to cues provided by standard HTTP headers to describe a page’s cacheability. These headers are the same ones used by browsers, so setting these headers correctly gives your app a double boost of speed when on Heroku: at the Varnish layer, and again at the user’s browser.

    If you don't know, Varnish is a really fast cache that sits between your application and the internet, essentially. When headers say it's safe to cache, Varnish does so and responds to additional requests with the cached object without ever hitting your application.