Caching
The pattern: put a faster, smaller storage layer in front of a slower, larger one. Reads hit the fast layer first; misses fall through to the slow layer; writes update both (or invalidate the cached entry). Caching is everywhere — CPU caches, page caches, DNS resolvers, CDNs, application caches, materialized views. Same pattern, different orders of magnitude.
The trade-off: freshness vs. speed, plus the eternal cache invalidation problem. Stale reads are fast but wrong. Strong invalidation is correct but slow and complex. Most production systems pick a TTL strategy (“good enough fresh”) plus targeted invalidation on writes. Cache stampedes — everyone misses simultaneously and hammers the slow layer — are the operational pitfall, solved by probabilistic early expiration, singleflight, or request coalescing. The hard part isn’t the cache; it’s invalidation, naming, and what to do when the slow layer dies and the cache has gone cold.
[Deepen Year 3 Phase 18 — Redis at the application layer with stampede prevention is where the pattern earns its weight.]
Related patterns
- state-vs-computation — caches are derivable state; the source of truth lives elsewhere.
- layering-and-abstraction — every cache is a layer; understanding what’s underneath is what saves you when it lies.
- mediation — the OS page cache is mediation that happens to also cache.
- materialized-views — caching applied to query results, with the same invalidation problem.
- eventual-consistency — TTL-based caches are eventual consistency with a clock.
- cardinality-as-cost — cache key cardinality is its own footgun.
- First touched: Year 1 Phase 3: Databases (Postgres + Redis).
- Deepened in: Year 3 Phase 18: Data Serving.
- Project where it lives: basecamp (Redis in Tier 1).