caching-strategies
Caching Strategies for Rails 8
Overview
Rails provides multiple caching layers:
- Fragment caching: Cache view partials
- Russian doll caching: Nested cache fragments
- Low-level caching: Cache arbitrary data
- HTTP caching: Browser and CDN caching
- Query caching: Automatic within requests
Quick Start
# config/environments/development.rb
config.action_controller.perform_caching = true
config.cache_store = :memory_store
# config/environments/production.rb
config.cache_store = :solid_cache_store # Rails 8 default
# OR
config.cache_store = :redis_cache_store, { url: ENV["REDIS_URL"] }
Enable caching in development:
bin/rails dev:cache
Cache Store Options
| Store | Use Case | Pros | Cons |
|---|---|---|---|
:memory_store |
Development | Fast, no setup | Not shared, limited size |
:solid_cache_store |
Production (Rails 8) | Database-backed, no Redis | Slightly slower |
:redis_cache_store |
Production | Fast, shared | Requires Redis |
:file_store |
Simple production | Persistent, no Redis | Slow, not shared |
:null_store |
Testing | No caching | N/A |
Fragment Caching
Basic Fragment Cache
<%# app/views/events/_event.html.erb %>
<% cache event do %>
<article class="event-card">
<h3><%= event.name %></h3>
<p><%= event.description %></p>
<time><%= l(event.event_date, format: :long) %></time>
<%= render event.venue %>
</article>
<% end %>
Cache Key Components
Rails generates cache keys from:
- Model name
- Model ID
updated_attimestamp- Template digest (automatic)
# Generated key example:
# views/events/123-20240115120000000000/abc123digest
Custom Cache Keys
<%# With version %>
<% cache [event, "v2"] do %>
...
<% end %>
<%# With user-specific content %>
<% cache [event, current_user] do %>
...
<% end %>
<%# With explicit key %>
<% cache "featured-events-#{Date.current}" do %>
<%= render @featured_events %>
<% end %>
Russian Doll Caching
Nested caches where inner caches are reused when outer cache is invalidated:
<%# app/views/events/show.html.erb %>
<% cache @event do %>
<h1><%= @event.name %></h1>
<section class="vendors">
<% @event.vendors.each do |vendor| %>
<% cache vendor do %>
<%= render partial: "vendors/card", locals: { vendor: vendor } %>
<% end %>
<% end %>
</section>
<section class="comments">
<% @event.comments.each do |comment| %>
<% cache comment do %>
<%= render comment %>
<% end %>
<% end %>
</section>
<% end %>
Use touch: true on belongs_to associations to cascade invalidation up the chain. See cache-invalidation.md for examples.
Collection Caching
Efficient Collection Rendering
<%# Caches each item individually %>
<%= render partial: "events/event", collection: @events, cached: true %>
<%# With custom cache key %>
<%= render partial: "events/event",
collection: @events,
cached: ->(event) { [event, current_user.admin?] } %>
Low-Level Caching
Use Rails.cache.fetch with a block for the most common pattern. See low-level-caching.md for:
- Basic read/write/fetch examples
- Caching in service objects
- Caching in query objects
- Instance variable memoization
- Request-scoped memoization with
CurrentAttributes
Cache Invalidation
Three strategies: time-based expiration, key-based expiration (using updated_at), and manual deletion. See cache-invalidation.md for:
- Time-based and key-based expiration
- Manual invalidation in model callbacks and services
- Pattern-based deletion (
delete_matched) touch: truefor Russian doll cascade- Built-in and custom counter caches
HTTP Caching
Use stale? for conditional GET (ETags/Last-Modified) and expires_in for Cache-Control headers. See http-caching-and-testing.md for full examples.
Testing Caching
Use a :caching metadata tag to enable caching in specs. See http-caching-and-testing.md for:
rails_helper.rbconfiguration- Testing cached view invalidation
- Testing cache invalidation in services
- Performance monitoring and instrumentation
Checklist
- Cache store configured for environment
- Fragment caching on expensive partials
-
touch: trueon belongs_to for Russian doll - Collection caching with
cached: true - Low-level caching for expensive queries
- Cache invalidation strategy defined
- Counter caches for counts
- HTTP caching headers for API
- Cache warming for cold starts (if needed)
- Monitoring for hit/miss rates
References
- low-level-caching.md - fetch/read/write, service objects, query objects, memoization
- cache-invalidation.md - expiration strategies, manual invalidation, touch, counter caches
- http-caching-and-testing.md - ETags, Cache-Control, spec configuration, monitoring