Speed Your Rails App with Model Caching using Redis.

While learning Rails, little emphasis is given on performance partly because most of those tutorials are usually small applications with minimal records. But as one progresses and starts handling huge apps, performance becomes critical. Optimizing queries and handling bottlenecks such as N + 1 query problem tops todo list. This is a challenge I have had to face and one of the best ways of improving performance is caching, in this case Model Caching. You can grab the code, having some other functionalities as well here Github repo

Getting started

We'll create a small app, I'll call mine SnippetDemo.

$ rails new SnippetDemo

Then scaffold snippet resources.

$ rails g scaffold Snippet content:text

We'll use rack-mini-profiler middleware to display the speed badge of our page. As well as Faker library to generate dummy data. Go ahead and add them to your gem file and run bundle install
In your db/seed.rb, and this to create dummy data
Then go ahead and seed that data.

$ rake seed

N/B: I'm creating 10k records, you could choose less. Point your home page to snippets index page in routes.rb
On loading loading the root page on your browser, these are my speeds info. Redis server

Using Redis

Redis is an in-memory key-value store that is fast & data retrieval is almost instantaneous & since we're using it to store cached data, you'll need to get it installed in your computer. For mac users: $ brew install redis For debian users: $ sudo apt-get install redis Start redis server

$ redis-server

You should something similar to this Redis server
We'll use Ruby client for Redis that helps us to connect to the redis instance easily. Add this to your gemfile
Then we instruct rails to use redis as cache store, in application.rb
Lastly, we initialize a wrapper around redis using redis-namespace. In initializers/redis.rb

Piecing it together

Instead of loading Snippets directly from the DB, as in the case in index action; @snippets = Snippet.all, we'll tweak it to this:
When we load for the first time, the snippet value on redis will be nil since no data has been pushed to it yet. We then instruct rails to push snippets to redis. All subsequent requests will thus fetch data from redis.

N/B since we're loading data on index page as json, you'll need to change where you call snippet.content to snippet["content"] on your views.

Looking at my speed badge, here's what I get. Redis server
Note there are no sql queries made. The downside with Redis is that it only stores strings.

By Victor Areba

Blog pic
I am a passionate Rubyist. This is a platform where I share what I have learned over the years in matters Ruby, Rails, JavaScript and other related technologies. I also write non technical stuff particulary creative writing here Inkulumo. I enjoy swimming and watching movies.


Manish Anand
01 February 2017
Hi, I have followed all your steps. But I'm getting following error; NoMethodError in Snippets#index undefined method `content' for #<Hash:0x007fd96f61be58> Did you mean? concern Extracted source (around line #16): <% @snippets.each do |snippet| %> <tr> <td><%= snippet.content %></td> <td><%= link_to 'Show', snippet %></td> <td><%= link_to 'Edit', edit_snippet_path(snippet) %></td> <td><%= link_to 'Destroy', snippet, method: :delete, data: { confirm: 'Are you sure?' } %></td> And also please explain, what is "site_point" in $redis = Redis::Namespace.new("site_point", :redis => Redis.new) Regards,.
Mauro Ponce
10 November 2018
I really like the way you paste Victor, what a developer! Could have change the namespace to something different than Site Point at least... Original article here: https://www.sitepoint.com/rails-model-caching-redis/.

Login to post your comment