Caching Strategies
The single highest-leverage performance technique available to a backend — and the one Phil Karlton called one of the two hard problems in computer science.
5.9.1Definition
Caching stores the result of an expensive operation — a database query, a rendered page, an API response — so a repeat request can be served instantly from memory instead of recomputed. Caches exist at multiple layers: in the browser, at a CDN edge (1.6), in an application-level store like Redis, or inside the database itself.
5.9.2Why It Exists
Most read requests ask for data that hasn't changed since the last time someone asked — recomputing it every single time wastes database load and adds latency for no benefit. Caching exists to exploit this repetition, at the cost of introducing the hardest problem in the discipline: knowing when cached data has gone stale and must be invalidated.
5.9.3Cache Layers & Invalidation Strategies
| Strategy | How it works | Risk |
|---|---|---|
| Time-based (TTL) | Cached value expires automatically after a fixed duration | Simple but can serve stale data until expiry |
| Write-through invalidation | Cache explicitly cleared/updated when underlying data changes | More accurate, more code paths to keep correct |
| CDN edge caching | Static or semi-static responses cached at edge nodes (1.6) | Excellent for public, non-personalized content |
5.9.4Common Mistakes
- Caching personalized data at a shared layer (like a CDN) with no per-user key, serving one user's private data to another.
- No invalidation path at all — data changes in the database but the cache continues serving the old value indefinitely until TTL expiry, which may be set far too long.
- Caching too aggressively during development, masking real bugs because a stale cached response looks identical to a correct one.
5.9.5Best Practices
- Cache the expensive, rarely-changing, widely-shared data first — that's where the leverage is highest.
- Always include a clear invalidation path, not just a TTL, for any data that changes based on user action.
- Key cached entries carefully to avoid cross-user data leakage in shared caches.