This blog is part of our Rails 5 series.

Rails 5 allows to cache HTTP responses forever by introducing http_cache_forever method.

Sometimes, we have static pages that never/rarely change.

# app/controllers/home_controller.rb class HomeController < ApplicationController def index render end end # app/views/home/index.html.erb < h1 > Welcome < /h1>

Let’s see log for the above action.

Processing by HomeController#index as HTML Rendered home/index.html.erb within layouts/application (1.3ms) Completed 200 OK in 224ms (Views: 212.4ms | ActiveRecord: 0.0ms) And so on for every request for this action.

There is no change in the response and still we are rendering same thing again and again and again.

Rails 5 introduces http_cache_forever

When response does not change then we want browsers and proxies to cache it for a long time.

Method http_cache_forever allows us to set response headers to tell browsers and proxies that response has not modified.

# app/controllers/home_controller.rb class HomeController < ApplicationController def index http_cache_forever ( public: true ) {} end end # OR class HomeController < ApplicationController def index http_cache_forever ( public: true ) do render end end end # app/views/home/index.html.erb < h1 > Welcome < /h1>

Now let’s look at the log for the modified code.

# When request is made for the first time. Processing by HomeController#index as HTML Rendered home/index.html.erb within layouts/application (1.3ms) Completed 200 OK in 224ms (Views: 212.4ms | ActiveRecord: 0.0ms) # For consecutive requests for the same page Processing by HomeController#index as HTML Completed 304 Not Modified in 2ms (ActiveRecord: 0.0ms)

On first hit, we serve the request normally but, then on each subsequent request cache is revalidated and a “304 Not Modified” response is sent to the browser.

Options with http_cache_forever

By default, HTTP responses are cached only on the user’s web browser. To allow proxies to cache the response, we can set public to true to indicate that they can serve the cached response.

Use http_cache_forever with caution

By using this method, Cache-Control: max-age=3155760000 is set as response header and browser/proxy won’t revalidate the resource back to the server unless force reload is done.

In case force reload is done, Cache-Control: max-age=0 is set as request header.

In this case, browser will receive the changed resource whether ETag is changed or not.