Rails caching with Redis


This guide will show how you can set up caching using Redis with an existing Rails app on Render. Caching is a technique that allows you to reuse a previous result from a computation or call to speed up the latency of most uses. For example, if you’re making requests against an external API and you can tolerate stale results, you can cache the result - reducing the amount of time to retrieve the data from hundreds of milliseconds to just a couple of milliseconds.

Rails gives you the ability to use different cache stores. While MemoryStore and FileStore can be sufficient in many use cases, using an external component for your cache like Redis has a couple of advantages:

  • Redis allows all you to share data between processes and instances. This is especially handy when you’re using a threaded server like Puma or if you have multiple server instances.
  • Redis is more persistent. On new deploys, new instances of your web service will be able to access cached results from your old instances.

The rest of the guide assumes you already have an existing Rails app. Follow our Rails quickstart to create one if you don’t.

Deploy to Render

We will first deploy a Redis instance on Render that is connected to your Rails app. There are 2 ways to deploy, either by declaring your services within your repository in a render.yaml file, or by manually setting up your services using the dashboard.

Use render.yaml to deploy

In your existing render.yaml , add the following:

services:
 - type: redis   name: cache   ipAllowList: [] # only allow internal connections   plan: free # optional (defaults to starter)   maxmemoryPolicy: allkeys-lfu # optional (defaults to allkeys-lru). Rails recommends allkeys-lfu as a default. - type: web # this example Rails service comes from https://render.com/docs/deploy-rails
   name: mysite
    env: ruby
    buildCommand: "./bin/render-build.sh"
    startCommand: "bundle exec puma -C config/puma.rb"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: mysite
          property: connectionString
      - key: RAILS_MASTER_KEY
        sync: false
      - key: REDIS_URL # this must match the name of the environment variable used in production.rb        fromService:          type: redis          name: cache          property: connectionString

This will create a new free Redis instance called cache with a maxmemory-policy set to allkeys-lfu. It also provides the connection string of the Redis instance to the Rails app as an environment variable called REDIS_URL.

Deploy Manually

If you don’t want to deploy your Rails app through a Blueprint, you can follow these steps for a manual deploy.

  1. Create a new Redis instance on Render. Note your Redis Internal Redis URL; you will need it later.

  2. Navigate to your Rails app service page. Select the Environment tab. Add the following environment variable:

    KeyValue
    REDIS_URLThe Internal Redis URL for the Redis you created above

Add RedisCacheStore to your Rails app

Now that you’ve deployed a Redis instance that is connected to your Rails app, we will configure the cache store used in production to be RedisCacheStore with the correct connection url.

  1. Add the following lines to your Gemfile. You may already have the redis gem installed.

    gem 'redis'
    
    # Use hiredis to get better performance than the "redis" gem
    gem 'hiredis'
  2. Edit the following lines in config/environments/production.rb:

    # Use a different cache store in production.
    config.cache_store = :redis_cache_store, {  url: ENV['REDIS_URL']}
  3. Commit all changes and push them to your Github repository.

That’s it! Render will redeploy the Rails app so that Rails will use the Redis instance created as its cache store. The official Caching with Rails guide is a great resource to check out next to figure out how to make the most use of your new Redis cache!