Skip to content

The Rails Low Level Cache

I think the Rails low level cache is the bees knees. It lets you store complicated values easily, manage TTLs, and improve the performance of your application.

I’d be remiss in stating that you shouldn’t cache until you need to.  Caches will introduce additional complexity into your application, make troubleshooting harder, and in general can be confusing.  How do you know if you need to introduce a cache?  Profile.  Using rack-mini-profiler is a great quick and dirty way to profile your code.

The rails low level cache is fairly simple to configure (especially if you’re using a PaaS like Heroku–you can drop in a managed memcached service easily).

From there, you need to build a cache key.  This is a string, up to 250 characters in length, that uniquely identifies whatever you’re trying to cache.  Basically anything that would cause a change in the contents of the cached object should be included in this key.  However, since you are going to calculate this key every time the value is requested, you don’t want the cache key to be expensive to calculate, otherwise the value of the cache will be degraded.  Good things for the key: timestamps, max updated_at values for a collection, user ids or roles.

Then, putting a value in the cache is as easy as:

def pull_from_cache
  cache_key = 'mykeyval'
  myval = Rails.cache.fetch(cache_key, expires_in: 1.hours) do
      @service.build_expensive_object()
  end
end

In the case above, the cached value will automatically expire in 1 hour.  If you don’t set the expiration time, then the cached value will eventually be removed via LRU.  How long that is depends on the size of your cache and what else you are putting in there.

If you want to test that something is being put in the cache, you can run a unit test and see how many times build_expensive_object() is called.

#...
object.service = @service
expect(@service).to receive(:build_expensive_object).once
object.pull_from_cache  
object.pull_from_cache
#...

In a production troubleshooting situation, you may need to evict something from the cache.  You can do so from the rails console by finding the cache key and running Rails.cache.delete('key').

Using the low level cache is a great way to push read heavy hot spots of your rails application (database queries or other complicated calculations) into memory and make your application faster.

Leave a Reply

Your email address will not be published. Required fields are marked *