--- name: solid-cache-coder description: Use when configuring or working with Solid Cache for database-backed caching. Applies Rails 8 conventions, cache key design, expiration strategies, database setup, and performance tuning patterns. allowed-tools: Read Write Edit Grep Glob Bash --- # Solid Cache Coder ## Overview Solid Cache is Rails 8's default cache backend—a database-backed cache store using NVMe storage instead of RAM. It eliminates the need for Redis/Memcached while providing FIFO eviction. ## Configuration ### Basic Setup ```ruby # config/environments/production.rb config.cache_store = :solid_cache_store ``` ### Advanced Configuration ```ruby config.cache_store = :solid_cache_store, { database: :cache, expires_in: 2.weeks, size_estimate: 500.megabytes, namespace: Rails.env, compressor: ZSTDCompressor } ``` ## Database Setup ### Separate Cache Database (Recommended) ```yaml # config/database.yml production: primary: <<: *default url: <%= ENV["DATABASE_URL"] %> cache: <<: *default url: <%= ENV["CACHE_DATABASE_URL"] %> migrations_paths: db/cache_migrate ``` ### Run Migrations ```bash bin/rails solid_cache:install:migrations bin/rails db:migrate ``` ## Cache Key Design ### Hierarchical Keys ```ruby Rails.cache.fetch("user:#{user.id}:profile:#{profile.id}") { expensive_computation } Rails.cache.delete_matched("user:#{user.id}:*") # Pattern-based deletion ``` ### Russian Doll Caching ```erb <% cache @post do %> <%= @post.body %> <% @post.comments.each do |comment| %> <% cache comment do %><%= render comment %><% end %> <% end %> <% end %> ``` ## Expiration Strategies ```ruby # Per-entry expiration Rails.cache.write("session:#{id}", data, expires_in: 30.minutes) # Fetch with expiration Rails.cache.fetch("expensive_query", expires_in: 15.minutes) { ExpensiveQuery.run } ``` ## Performance Tuning ### Enable ZSTD Compression ```ruby config.cache_store = :solid_cache_store, { compressor: ZSTDCompressor } ``` ### Batch Operations ```ruby keys = users.map { |u| "user:#{u.id}:preferences" } results = Rails.cache.read_multi(*keys) Rails.cache.fetch_multi(*keys) { |key| compute_value_for(key) } ``` ## Database Maintenance ```ruby # lib/tasks/cache_maintenance.rake namespace :cache do task vacuum: :environment do ActiveRecord::Base.connected_to(database: :cache) do ActiveRecord::Base.connection.execute("VACUUM ANALYZE solid_cache_entries") end end end ``` ## Solid Cache vs Redis | Choose Solid Cache When | Choose Redis When | |------------------------|-------------------| | Simplifying infrastructure | Sub-millisecond latency critical | | Using PostgreSQL/SQLite as primary | Extremely large cache working set | | Single-server or small clusters | Need pub/sub or complex invalidation | | Preferring NVMe over RAM caching | Already running Redis | ## Anti-Patterns | Anti-Pattern | Problem | Solution | |--------------|---------|----------| | Single database at scale | Resource contention | Separate cache database | | No compression | Wasted storage | Enable ZSTD | | Infinite expiration | Unbounded growth | Set reasonable max_age | | No maintenance | Table bloat | Schedule VACUUM | ## Output Format When configuring Solid Cache, provide: 1. **Database Setup** - Multi-database configuration 2. **Cache Config** - Store options and expiration 3. **Performance** - Compression and pool settings 4. **Maintenance** - Cleanup tasks and schedules