[Ruby on Rails (RoR)] Use Redis Cache Store in Rails

Redis Cache Store

The Redis cache store takes advantage of Redis support for automatic eviction when it reaches max memory, allowing it to behave much like a Memcached cache server.


Deployment note: Redis doesn’t expire keys by default, so take care to use a dedicated Redis cache server. Don’t fill up your persistent-Redis server with volatile cache data! Read the Redis cache server setup guide in detail.


For a cache-only Redis server, set maxmemory-policy to one of the variants of allkeys. Redis 4+ supports least-frequently-used eviction (allkeys-lfu), an excellent default choice. Redis 3 and earlier should use least-recently-used eviction (allkeys-lru).

Set cache read and write timeouts relatively low. Regenerating a cached value is often faster than waiting more than a second to retrieve it. Both read and write timeouts default to 1 second, but may be set lower if your network is consistently low-latency.

By default, the cache store will not attempt to reconnect to Redis if the connection fails during a request. If you experience frequent disconnects you may wish to enable reconnect attempts.

Cache reads and writes never raise exceptions; they just return nil instead, behaving as if there was nothing in the cache. To gauge whether your cache is hitting exceptions, you may provide an error_handler to report to an exception gathering service. It must accept three keyword arguments: method, the cache store method that was originally called; returning, the value that was returned to the user, typically nil; and exception, the exception that was rescued.

Use :redis_cache_store >= Rails 5.2

Rails 5.2.0 includes a Redis cache store out of the boxBuilt-in Redis cache store by jeremy · Pull Request #31134 · rails/rails · GitHub - https://github.com/rails/rails/pull/31134, so you don’t really need this gem anymore if you just need to store the fragment cache in Redis. Maintenance on the redis-activesupport gem will continue for security and compatibility issues, but we are no longer accepting new features. We are still actively maintaining all other gems in the redis-store family, such as [redis-actionpack for session management, and redis-rack-cache for HTTP cache storage.

To get started, add the redis gem to your Gemfile:

1
2
3
4
5
# Gemfile

# GitHub - redis/redis-rb: A Ruby client library for Redis
# https://github.com/redis/redis-rb
gem 'redis', '4.3.1'

You can enable support for the faster hiredis connection library by additionally adding its ruby wrapper to your Gemfile:

1
2
3
4
5
# Gemfile

# redis/hiredis-rb: Ruby wrapper for hiredis
# https://github.com/redis/hiredis-rb
gem 'hiredis', '0.6.3'

Redis cache store will automatically require & use hiredis if available. No further configuration is needed.

Finally, add the configuration in the config/environment.rb or relevant config/environments/*.rb file:

1
config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'] }

A more complex, production Redis cache store may look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# config/environment.rb or config/environments/*.rb

cache_servers = %w(redis://cache-01:6379/0 redis://cache-02:6379/0)
config.cache_store = :redis_cache_store, { url: cache_servers,

connect_timeout: 30, # Defaults to 20 seconds
read_timeout: 0.2, # Defaults to 1 second
write_timeout: 0.2, # Defaults to 1 second
reconnect_attempts: 1, # Defaults to 0

error_handler: -> (method:, returning:, exception:) {
# Report errors to Sentry as warnings
Raven.capture_exception exception, level: 'warning',
tags: { method: method, returning: returning }
}
}

More configuration examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Defaults to `redis://localhost:6379/0`
config.cache_store = :redis_cache_store

# Supports all common cache store options (:namespace, :compress,
# :compress_threshold, :expires_in, :race_condition_tool) and all
# Redis options.
cache_password = Rails.application.secrets.redis_cache_password
config.cache_store = :redis_cache_store, driver: :hiredis,
namespace: 'myapp-cache', compress: true, timeout: 1,
url: "redis://:#{cache_password}@myapp-cache-1:6379/0"

# Supports Redis::Distributed with multiple hosts
config.cache_store = :redis_cache_store, driver: :hiredis
namespace: 'myapp-cache', compress: true,
url: %w[
redis://myapp-cache-1:6379/0
redis://myapp-cache-1:6380/0
redis://myapp-cache-2:6379/0
redis://myapp-cache-2:6380/0
redis://myapp-cache-3:6379/0
redis://myapp-cache-3:6380/0
]

# Or pass a builder block
config.cache_store = :redis_cache_store,
namespace: 'myapp-cache', compress: true,
redis: -> { Redis.new … }

Use :redis_store < Rails 5.2

1
2
3
4
5
# Gemfile

# GitHub - redis-store/redis-rails: Redis stores for Ruby on Rails
# https://github.com/redis-store/redis-rails
gem 'redis-rails', '5.0.2'
1
config.cache_store = :redis_store, { url: ENV['REDIS_URL'] }

References

[1] Caching with Rails: An Overview — Ruby on Rails Guides - https://guides.rubyonrails.org/caching_with_rails.html

[2] ActiveSupport::Cache::RedisCacheStore - https://api.rubyonrails.org/classes/ActiveSupport/Cache/RedisCacheStore.html

[3] Built-in Redis cache store by jeremy · Pull Request #31134 · rails/rails · GitHub - https://github.com/rails/rails/pull/31134

[4] New Feature on Rails 5.2: Redis Cache Store - https://blog.engineyard.com/rails-5-2-redis-cache-store

[5] Configuration Cache and Rails Session Store with Redis | by Kirill Shevchenko | Medium - https://kirillshevch.medium.com/configuration-cache-and-rails-session-store-with-redis-b3ce6f64d1fc

[6] GitHub - redis-store/redis-rails: Redis stores for Ruby on Rails - https://github.com/redis-store/redis-rails

[7] GitHub - redis-store/redis-activesupport: Redis stores for ActiveSupport - https://github.com/redis-store/redis-activesupport

[8] redis-activesupport | RubyGems.org | your community gem host - https://rubygems.org/gems/redis-activesupport

[9] redis-activesupport by redis-store - http://redis-store.org/redis-activesupport/

[10] How to Use The Redis Database in Ruby - RubyGuides - https://www.rubyguides.com/2019/04/ruby-redis/

[11] Ruby on Rails Redis installation and configuration - Hix on Rails - https://hixonrails.com/ruby-on-rails-tutorials/ruby-on-rails-redis-installation-and-configuration/

[12] GitHub - redis-store/redis-rack-cache: Redis stores for Rack::Cache - https://github.com/redis-store/redis-rack-cache

[13] GitHub - redis-store/redis-actionpack: Redis stores for ActionPack - https://github.com/redis-store/redis-actionpack

[14] Redis - https://redis.io/