caching in Rails

notes about caching in Rails.


  1. https://www.nateberkopec.com/2015/07/15/the-complete-guide-to-rails-caching.html

general

caching:

response-time threshold for user is 1 second or less (from the moment of click till DOM finishes painting).

but this includes:

=> server response should be below ~300ms

profiling

applications must be profiled:

MAART - maximum acceptable average response time (e.g. 50ms)

3rd party tools

Rails logs

total time is the important one.

Views time might include executing queries since AR relations are lazily loaded ActiveRecord time is actual time spent in DB

caching techniques

complicated part of caching is knowing when to expire caches.

key-based cache expiration

key-based expiration is a cache expiration strategy that expires entries in the cache by making cache key contain information about the value being cached -> when object changes cache key changes as well. previous cache key is never used again and cache store expires when it, say, runs out of memory - we never expire cache keys manually.

using touch option on belongs_to associations allows to update associated object whenever current object is touched or saved.

cache key used in fragment caching:

views/todos/123-20120806214154/7a1156131a6928cb0026877f8b749ac9

which means:

views/<object.class.name.underscore.pluralize>/<object.id>-<object.updated_at>/<md5 sum of template tree>

changing either object itself or template tree expires cache key (actually cache keys are not expired - they are just left unused).

when array is used as cache key for cache final cache key is a concatenated version of everything in the array (with / as delimiter).

russian doll caching

russian doll caching:

2 ways to make key-based cache expiration work:

  1. use compound cache key like:
cache ["todo_list", @todos.map(&:id), @todos.maximum(:updated_at)]

whenever todo is added/removed/changed cache expires.

  1. use touch option on belongs_to associations as described above

cache digests

  1. https://github.com/rails/cache_digests

cache digests were included in Rails 4 and had been available as a gem before.

prior to cache digests it was necessary to expire fragment caches explicitly when changing template by adding, say, version v1 to cache key. now cache key contains md5 sum of template tree (template file itself and all of its dependencies) - whenever template changes cache expires.

cache backends

ActiveSupport::FileStore

pros:

cons:

ActiveSupport::MemoryStore

pros:

cons:

Memcache and dalli

pros:

cons:

Redis and redis-store

pros:

cons:

LRURedux

pros:

cons: