Redis-Powered Server-Side Caching in Rails

Reduce server load and improve the speed of your Rails application with Redis cache stores.

Krutik Patel
Simform Engineering
5 min readNov 28, 2023

--

Caching is a crucial mechanism employed in web development to enhance the efficiency of HTTP responses. It enables browsers, servers, and intermediary systems to store and reuse previously fetched HTTP responses. By doing so, it significantly reduces the loading time of subsequent requests and lightens the server’s load.

Essentially, caching is a powerful tool for accelerating web page loading speeds. In web development, there are four primary types of caching:

  1. Browser Caching
  2. Proxy Caching
  3. Server-side Caching
  4. CDN Caching

Here, we will focus on harnessing the benefits of server-side caching in a Rails application.

Server-side Caching in Rails

Server-side caching plays a pivotal role in Rails applications, offering several key benefits that are crucial for optimizing web application performance. Here’s an overview of its importance:

  1. Enhanced Performance: Server-side caching accelerates web page loading speed by storing frequently accessed data for quick retrieval.
  2. Reduced Database load: Caching minimizes the need to constantly query the database and speeds up responses.
  3. Lower Latency: Caching reduces latency by serving precomputed content directly from memory, eliminating time-consuming processing.
  4. Scalability: Caching enables Rails applications to handle a greater number of requests without proportional resource increases, enhancing scalability.
  5. Improved User Experience: Faster response times and reduced waiting times create a more encouraging user engagement.
  6. SEO Benefits: Caching improves website loading speed, positively impacting search engine rankings and visibility.
  7. Reliability: Caching ensures consistent content delivery, even during backend or database issues, improving the application’s reliability and user experience.

Redis in Rails

Redis is an open-source, in-memory data store used for various data storage and processing tasks. It is designed for high-performance, low-latency data access and is commonly used as a caching mechanism, message broker, and data storage solution in web applications, including Rails applications.

Redis is particularly useful in a Rails application for:

  1. Caching
  2. Session Store
  3. Real-time Features
  4. Background Jobs
  5. Data Structures

Redis is frequently used for caching frequently accessed data in Rails applications. It reduces the need to fetch the same data from a database repeatedly, leading to significant performance improvements.

workings of server-side caching

If data in our database is not frequently changing, it is always a good practice to use serverside caching and store that data in cache. This way other requests will find that data from the cache without even executing any query and also the server load will be reduced as well.

Implementation

In this blog post, we’ll explore the practical implementation of server-side caching using the Redis service within a Rails application. By doing so, we’ll unlock the various advantages and performance benefits that server-side caching has to offer.

For this article, we will use the following gems:

  • redis-rails (5.0.2)
  • redis-namespace (1.11.0)
  • redis-rails (5.0.2)
  • redis-rack-cache (2.2.1)
  • faker (3.2.0)

Project setup:

Create a new Rails project named ‘redis-caching’ using PostgreSQL as the database:

>> rails new redis-caching -d postgresql
>> cd redis-caching

Now, go to the Gemfile, include the following gems, and run the ‘bundle install’ command in your console.

gem 'redis-rails'
gem 'redis-namespace'
gem 'redis-rack-cache'
gem 'faker'

Here, we will generate a Post model. Write the following lines in db/seeds.rb to create 3 random post records.

console 
>> rails g model post title:string content:text

db/seeds.rb
3.times do
Post.create!(
title: Faker::Lorem.sentence,
content: Faker::Lorem.paragraph
)
end

Then, execute the following command to your console to create the database, migrate all the migration files, and create seed data. Next, create PostsController with only index action and update config/routes.rb file.

console 
>> rails db:create db:migrate db:seed
>> rails g controller posts index

config/routes.rb
get 'posts', to: 'posts#index'

Redis Configurations:

Create a new file in the config/initializers folder and name it ‘redis.rb’. Initialize the new Redis instance with the new Redis namespace and store it in a global variable, $redis.

config/initializers/redis.rb
$redis = Redis::Namespace.new("redis_caching", redis: Redis.new)

Here, redis_caching is a unique namespace. If we share the same database and Redis server across multiple applications, we can create different application-wise namespaces using Redis::Namespace, a feature provided by the redis-namespace gem.

Now, to tell the application server to use the Redis cache as a caching storage, add the following line to the config/application.rb file.

config/application.rb
config.cache_store = :redis_store, 'redis://localhost:6379/0/cache', {expires_in: 10.seconds, size: 15.megabytes}

As mentioned in the above syntax, the application server now uses redis_store as its cache storage, with the cache set to expire after 10 seconds. We can store a maximum of 15 megabytes of data.

During the initial 10 seconds after setting the data into the cache, the query remains dormant, and the cache readily provides the required records. After 10 seconds, If a request is made by a user then the query will be executed, and fetched records will be stored in Redis cache for the next 10 seconds.

Fetching Records:

In the ‘app/helpers’ folder, you’ll find the posts_helper.rb file within the PostsHelper module. The logic in this file is as follows:

def fetching_posts
posts = $redis.get('posts') rescue nil

if posts.nil?
posts = Post.all.to_json
$redis.set('posts', posts)
$redis.expire("posts", 10.seconds.to_i)
end

posts = JSON.load posts
end

Here, we have created a fetching_posts function, which attempts to retrieve the data with the posts key in Redis. If the key is not found, we set it to nil. Subsequently, we check if the posts variable is nil. If it is, the data is fetched from the database by executing the query and then stored in the Redis cache with the ‘posts’ key.

Now, in the PostsController, we include this helper module and call the fetching_posts method in the index action.

class PostsController < ApplicationController

include PostsHelper

def index
@posts = fetching_posts

render json: @posts
end
end

The response is rendered in JSON format. To observe the functionality, start the Rails server, initiate the Redis server in a new tab, and open another tab to monitor Redis.

rails server:
>> rails s
redis server:
>> redis-server
monitor redis:
>> redis-cli monitor

Visit http://localhost:3000/posts in your browser, where you’ll find the post data in JSON format.

Now, reload the page several times and check out the Redis monitor logs.

Redis monitor

I hope this clarifies the process. If you have further inquiries or require additional information on a specific topic, feel free to ask.

Thank you for reading the article.

Happy coding, and happy caching!

Follow the Simform Engineering to know more about such insights and the latest trends in the development ecosystem.

Connect with us: Twitter | LinkedIn

--

--