Rails caching strategies for performance

Sarah Mitchell Feb 2026
4 tabs
<%# Fragment caching - caches rendered HTML %>
<% cache @product do %>
  <h1><%= @product.name %></h1>
  <p><%= @product.description %></p>
  <p>Price: $<%= @product.price %></p>
<% end %>

<%# Cache with specific key %>
<% cache ['products', @product.id, @product.updated_at] do %>
  <%= render @product %>
<% end %>

<%# Russian doll caching - nested fragments %>
<% cache @post do %>
  <h1><%= @post.title %></h1>

  <% cache ['comments', @post.comments.maximum(:updated_at)] do %>
    <% @post.comments.each do |comment| %>
      <% cache comment do %>
        <%= render comment %>
      <% end %>
    <% end %>
  <% end %>
<% end %>

<%# Conditional caching %>
<% cache_if user_signed_in?, @product do %>
  <%= render 'detailed_product', product: @product %>
<% end %>

<%# Collection caching %>
<%= render partial: 'products/product', collection: @products, cached: true %>
4 files · erb, ruby Explain with highlit

Rails caching dramatically improves performance by avoiding expensive computations and queries. Fragment caching caches view partials. Russian doll caching nests cache fragments for efficient invalidation. Low-level caching stores arbitrary data. Rails.cache.fetch simplifies cache-or-compute pattern. Cache keys use model touch for automatic invalidation. I use memcached or Redis for distributed caching. Counter caches avoid COUNT queries. Query result caching prevents duplicate queries in request. HTTP caching with ETags and Last-Modified headers reduces server load. Cache sweepers invalidate stale data. Proper caching strategy balances freshness against performance. Understanding cache invalidation is crucial—Phil Karlton said naming and cache invalidation are the two hard problems in computer science.