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
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.
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
You should something similar to this
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,
Lastly, we initialize a wrapper around redis using redis-namespace.
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.
Note there are no sql queries made.
The downside with Redis is that it only stores strings.