Mar 5

Your Cache Sucks: 7 Ways You’re Doing Caching Wrong

Blog post's hero image

Caching plays a crucial role in optimizing performance and improving user experience across various systems. However, as those who have attempted to build their own cache will tell you, this road is riddled with pitfalls that almost everyone falls into. In this blog, we will explore the seven most common issues that can screw up your caching, and we’ll provide insights on how to overcome them effectively.

If your cache sucks, here’s what you’re probably doing wrong:

1. You can only cache the entire request or nothing

One significant problem is the inability to cache specific parts of requests, e.g. only certain fields of objects returned from an API. For many use cases, some parts are static and can be easily cached, but others may be personalized or frequently updated.

This discrepancy reduces the overall cache hit rate because it means that if your data has even a single non-cacheable field, you can't cache the whole thing—even if the whole rest of it is cacheable.

For example, for e-commerce stores, products have a static and public title, description, images, etc. but if the user sees a personalized price or if there is "viewerPreviouslyOrdered" field, the entire query is uncacheable.

To address this, it's essential to identify the non-cacheable elements and design caching mechanisms that can cache the parts of your data that are cacheable, even if some parts are non-cacheable.

2. Lack of Observability

Insufficient observability of how your cache is behaving can lead to challenges in identifying and resolving issues. Monitoring cache hit rates alone is not enough; organizations need to drill down into individual requests and understand how and why they are being cached. This visibility enables better troubleshooting and ensures that customer support agents are aware of any caching-related issues.

If a user contacts your support team with an issue akin to 'I did something but the update is not showing up,' that is a caching issue and your support team needs to be able to check that specific request and what happened with it.

3. Limited Understanding of Cacheability

Understanding the cacheability of different data types and requests is crucial. Not all data is equally cacheable, as it might be accessed rarely, might be personalized, might change frequently, etc., and having insight into these patterns allows for better cache configuration.

You can calculate how cacheable certain data is by keeping track of hashes of incoming variables and outgoing responses and calculating how often the data stays the same for repeated accesses of the same variables.

By identifying cacheable data and tailoring caching strategies accordingly, organizations enable their developers to achieve higher cache hit rates.

4. Separation of Cache Configuration and Code

Often, cache configuration is detached from where data is defined and code is written. This separation can lead to inconsistencies and increase the risk of issues and incidents because changes don’t go through the proper software development life cycle, including review processes and approvals.

5. Challenges in Cache Invalidation

Cache invalidation, a complex problem in computer science, can result in stale data being served to users if done incorrectly.

It's often difficult to identify which entries to invalidate when data changes, for example if a product availability changes it might be reordered on the category page, which needs to update the cache for all paginated lists in that category.

Implementing safe cache invalidation strategies is crucial to maintaining data freshness and avoiding user dissatisfaction.

6. Lack of Insights into Cache Invalidation

Even when cache invalidation strategies are in place, organizations often lack visibility into the effectiveness of these mechanisms.

It is essential to have insights into which cache invalidation calls are triggered, why they are triggered, and how they impact different data types. This information helps in troubleshooting and improving cache invalidation processes.

7. Insufficient Granularity in Caching

Caching at either the individual user level or for all users may not provide the desired cacheability in certain scenarios. Organizations often need to cache data for specific groups, such as teams or users enrolled in a particular AB test. By implementing caching mechanisms that allow for granular caching based on JWT claims or AB test enrollment, organizations can improve cache utilization and enhance performance.

Conclusion

Optimizing caching strategies is essential for maximizing performance and delivering exceptional user experiences. By addressing common problems such as incomplete data caching, lack of observability, limited understanding of cacheability, separation of cache configuration and code, cache invalidation challenges, lack of insights into cache invalidation, and insufficient granularity in caching, organizations can overcome caching obstacles and achieve higher cache hit rates. By implementing best practices and continuously evaluating and refining caching processes, companies can unlock the full potential of caching and provide optimal user experiences.