Readyset Docs

Connect Readyset Cache to Ruby on Rails

This guide walks you through how to use Readyset Cache with your Ruby on Rails app. To do this, you'll use the built-in Rails multiple database support to get the performance of caching with the simplicity of a single read replica.

0. Set up Readyset Cache

First, you'll set up Readyset Cache using Docker.

  1. Make sure your database is configured for Readyset Cache
  2. Install Readyset Cache

1. Configure Rails in three steps

Ruby On Rails allows you to configure Readyset Cache as a read replica and define a time window after writes for when to switch read traffic over to Readyset Cache. This allows clients to observe recent writes if there is write traffic ongoing while still taking advantage of Readyset Cache's caching for read-heavy workloads.

This will take three steps. You'll need to add Readyset Cache as a read replica, then configure ActiveRecord to route traffic, and finally configure Rails' connection switching middleware with a few quick changes.

a. Update database configuration

Taking advantage of Readyset Cache means defining a read replica of your primary database. Rails makes this incredibly simple and in the case of Readyset Cache, you'll configure the replica to point to your Readyset Cache instance. We recommend following Rails established patterns and name your primary database as primary and then your read replica Readyset Cache instance as primary_replica.

For instance, your database.yml file will look something like this:

production:
  primary:
    database: my_primary_database
    username: root
    password: <%= ENV['ROOT_PASSWORD'] %>
    adapter: postgresql
  primary_replica:
    database: my_primary_database
    username: root
    password: <%= ENV['READYSET_PASSWORD'] %>
    host: <%= ENV['READYSET_HOST'] %>
    port: 5433
    adapter: postgresql
    replica: true
    database_tasks: false

It's important to note that the primary_replica definition points to Readyset Cache and that two flags are set: replica is true and database_tasks is false. The database_tasks flag will disable Rails database migrations running against Readyset Cache. This isn't needed as Readyset Cache will see any changes to the primary database already.

b. Update ApplicationRecord to use two connections

In your application's app/models directory, you'll find a base class for all of your model classes often called ApplicationRecord. Open up that class and add the following line:

connects_to database: { writing: :primary, reading: :primary_replica }

If you haven't made any changes to this base class, it should look like this:

class ApplicationRecord < ActiveRecord::Base
  primary_abstract_class

  connects_to database: { writing: :primary, reading: :primary_replica }
end

Note how connects_to database: is pointing to the names of both the primary database and Readyset Cache via the names you defined in your database.yml configuration.

If you aren't on Rails 7, you'll need to replace primary_abstract_class with self.abstract_class = true. What's more, if for some reason you do not have access to an ApplicationRecord base class, you'll need to monkey patch one.

c. Activate connection switching middleware

Finally, you'll need to activate Rails middleware that'll ensure writes go to the primary database and reads through Readyset Cache. First run this command to generate a configuration file:

bin/rails generate active_record:multi_db

This command will create a new file: config/initializers/multi_db.rb. Open up that file and uncomment the following lines:

Rails.application.configure do
  config.active_record.database_selector = { delay: 2.seconds }
  config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
  config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end

It's important to note that a delay of 2 seconds is designed to ensure the read replica (in this case Readyset Cache) is consistent with writes that are going directly to the primary database.

You're off to the races!

At this point, if you start your Rails application, read requests will go directly to Readyset Cache and writes will go to your primary Postgres database. You'll next need to configure which SQL select statements (i.e. reads) you'll want to cache. Check out our caching guide for more information.