.claude/skills/caching-strategies/SKILL.md
Implements Rails caching patterns for performance optimization. Use when adding fragment caching, Russian doll caching, low-level caching, cache invalidation, or when user mentions caching, performance, cache keys, or memoization. WHEN NOT: General query optimization (use performance-optimization), background job processing, or problems caused by N+1 queries rather than missing caches.
npx skillsauth add ThibautBaissac/rails_ai_agents caching-strategiesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Rails provides multiple caching layers:
# 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
| 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 |
<%# 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 %>
Rails generates cache keys from:
updated_at timestamp# Generated key example:
# views/events/123-20240115120000000000/abc123digest
<%# 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 %>
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.
<%# 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?] } %>
Use Rails.cache.fetch with a block for the most common pattern. See low-level-caching.md for:
CurrentAttributesThree strategies: time-based expiration, key-based expiration (using updated_at), and manual deletion. See cache-invalidation.md for:
delete_matched)touch: true for Russian doll cascadeUse stale? for conditional GET (ETags/Last-Modified) and expires_in for Cache-Control headers. See http-caching-and-testing.md for full examples.
Use a :caching metadata tag to enable caching in specs. See http-caching-and-testing.md for:
rails_helper.rb configurationtouch: true on belongs_to for Russian dollcached: truedevelopment
Creates Turbo Streams, Turbo Frames, and morphing patterns for real-time UI updates. Use when adding real-time updates, partial page rendering, form submissions, or broadcasting. WHEN NOT: For Stimulus JavaScript controllers (see stimulus-patterns skill). For general view conventions (see rules/views.md).
testing
Writes Minitest tests with fixtures following 37signals conventions. Uses Minitest (not RSpec) and fixtures (not factories). Use when writing tests, adding test coverage, or creating fixtures. WHEN NOT: For RSpec or FactoryBot patterns (this project uses Minitest + fixtures exclusively). For test configuration/CI setup (see project docs).
tools
Builds focused, single-purpose Stimulus controllers for progressive enhancement. Use when adding JavaScript behavior, UI interactions, form enhancements, or building reusable client-side components. WHEN NOT: For Turbo Stream/Frame patterns (see turbo-patterns skill). For server-side view logic (see rules/views.md).
testing
Implements the state-as-records-not-booleans pattern for rich state tracking. Use when modeling state changes, replacing boolean flags with record-based state, or when user mentions state records, closures, publications, or toggling state. WHEN NOT: Technical flags like cached/processed (use booleans), concern extraction (use concern-patterns), general model work (use model-patterns).