Caching Lessons Learned

We have a set of bugs with caching:

Versioning:

  • We must version whenever we cache so that we when upgrade, the app uses the updated revision of the cached object
  • In acts_as_cached, there is a version. However, in page caching and fragment caching there is no version number.
  • In page caching, the cached page is saved on disk. Our deployment method overwrites the directory which will refresh this cache.
  • In this case, we should use the same workaround we use in css, icon, and js includes where we define the key as name?<version_number>

Includes:

  • Early on, we used :include in acts_as_cached so that we minimize the number of database calls. However, by over including you can accidentally max out your network. The include is implemented as a big join so if you have m includes where one column has a large amount of data, you will transfer n^m data.
  • We have seen this where we had a column that returns results in the order of 10K, but instead of transfering 60 rows of 10K (600K), we were transferring 10^6 * 10K rows (100MB). Now, that’s a huge difference!

Expiry:

  • We use fragment caching to save rendering in our views. However, the base implementation from rails does not support expiry.
  • Thus, we need to either explicitly expire or use another technique to expire like TTL expire or sweepers

Leave a Reply