Caching Pitfalls and Practice

Caching giveth performance and taketh away your sanity. The same technique that makes systems fast introduces a whole category of subtle, intermittent, hard-to-debug problems — stale data that appears randomly, a cache that collapses under load at the worst moment, bugs that only happen when the cache is cold or full. This closing post catalogs the pitfalls that bite real systems, and distills the practical wisdom of the series: cache deliberately, expect the failure modes, and remember that the two genuinely hard things are still hard.

This final post covers caching pitfalls — the failure modes that bite real systems (cache stampede, staleness bugs, penetration, and more) — and the practical wisdom of caching well, tying the series together. It’s the “what goes wrong and how to cache responsibly” post, synthesizing the series’ lessons into practical guidance. Because caching’s power comes with real, recurring pitfalls, knowing them is essential to caching well.

Cache stampede (thundering herd)

A classic, dangerous caching pitfall is the cache stampede (or “thundering herd”) — many requests hammering the source at once when a cache entry expires:

Cache stampede (thundering herd) — many simultaneous misses for a popular expired item flooding the source at once, potentially overwhelming it and cascading to failure — is a classic dangerous pitfall, prevented by locking (one recompute), staggered/early expiration, and serve-stale-while-revalidating. It’s a case where the cache’s absence causes an outage. It’s not the only counterintuitive failure mode.

More pitfalls

Beyond stampede, several other caching pitfalls bite real systems — worth knowing to avoid them:

Caching pitfalls — staleness bugs (subtle, intermittent wrong data from stale caches — a top source of baffling bugs), cache penetration (requests for non-existent data bypassing the cache to the source), cold cache (empty cache after restart offering no protection until warmed), and over-caching (needless complexity/staleness) — bite real systems alongside stampede. Knowing them is essential to caching well. They all stem from caching’s inherent tradeoffs.

When not to cache

A crucial piece of caching wisdom, echoing the whole series: know when NOT to cache — because caching isn’t free, and inappropriate caching causes more harm than good:

Knowing when not to cache — small benefit (rarely-reused/cheap data), consistency-critical changing data, or masking a fixable problem — is essential caching wisdom: cache deliberately where the benefit justifies the cost, not reflexively. This “right tool for the need” discipline recurs across the blog’s engineering series. It’s the counterweight to caching’s appeal.

Caching well: the practical wisdom

To close the series, the distilled practical wisdom of caching well:

Caching well means maximizing the hit rate on the right (hot, expensive, tolerant) data, navigating the hard invalidation problem by choosing a consistency point (usually bounded staleness/TTL), anticipating the failure modes (stampede, cold cache, penetration, staleness), and caching deliberately where the benefit justifies the cost. That completes the series: from why caching exists (locality, the memory hierarchy) through fundamentals, eviction, invalidation, patterns, distributed caching, and web/CDN caching, to pitfalls and practice. Caching is a universal, powerful, and genuinely subtle technique — respect both its power and its difficulty, and cache deliberately.

Key takeaways

Further reading

Sources & References

The thundering-herd pitfall
Caching in practice