Best for
- Systems recomputing the same expensive answer all day
- Caches added ad hoc that now serve stale data mysteriously
- Deciding cache layers deliberately instead of sprinkling them
What you give it
- The hot paths and their current costs, and what staleness each can tolerate
What you get back
- A cache map: per candidate, the layer, the key design, the lifetime, the invalidation path
- Staleness decisions made explicit: what may be seconds old, what must never be
- The safety rules enforced: rebuildable from source, flush-safe, and the stampede handled
How it works
- Selects candidates by the ratio: read frequency x computation cost x tolerance for staleness.
- Forces the staleness question per item — 'how old may this be?' is a business decision made explicit, not a TTL guessed.
- Designs keys to include every dimension that changes the answer — the missed dimension is the classic wrong-data bug.
- Chooses invalidation per item: TTL for the tolerant, event-driven for the must-be-fresh, versioned keys for the deploy-coupled.
Example
You: Our product pages hit the database 40 times each and the catalogue rarely changes. Design the caching.
Result: Three layers, each with a reason: the rendered page fragment cached 5 minutes (stampede-protected), the price NOT cached beyond the request (business rule: price changes take effect immediately — found by asking, not assuming), the category tree cached an hour with event invalidation on edits. Keys designed to include locale and currency (the bug-in-waiting found in review). Flush test passed: cold caches, correct pages, 2.1s rebuild.
Limits — please read
- The source of truth stays the backend store, always; any design where cache loss loses data is refused on principle.
- Event invalidation needs the events to exist; missing ones are named as prerequisites.
- Cache layers add operational surface; the map includes what to monitor (hit rates, stampedes, stale serves).