I like caches that are easy to delete.
That may sound strange, because the whole point of a cache is that it improves something important: latency, cost, load, or availability. But the safest caches are the ones the system can survive without. They make the steady state better without becoming the only thing holding correctness together.
That usually means the cache is boring.
Exact keys. Simple values. Clear TTLs. Obvious invalidation. Metrics. A fallback path. No clever inference that future maintainers have to rediscover during an incident.
What Makes a Cache Boring
A boring cache has a small contract.
Given this exact key, return the recently stored value if it exists.
It does not try to become a database. It does not hide business rules inside serialization code. It does not require five services to update it in exactly the right order. It does not make correctness depend on a best-effort write that nobody can replay.
The boring cache is an optimization. The source of truth remains somewhere else.
Exact Beats Clever
Approximate structures are powerful, but they are easy to misuse.
Bloom filters, Cuckoo filters, sampled caches, and lossy sketches all have places where they shine. They are excellent when the direction of error is safe. They are risky when a false positive or an operationally incomplete view can suppress work that should have happened.
Before using an approximate cache, ask:
- What does a false positive do?
- What does a false negative do?
- Can the structure be rebuilt completely?
- What happens if updates are missed during an outage?
- Is the approximation mathematical, operational, or both?
The last question matters. A data structure may have no false negatives in theory while the system still has false negatives because the structure did not observe every write.
That is not a data structure problem. It is a system design problem.
TTLs Are a Safety Net
I like TTLs because they give a cache a half-life.
They make stale state temporary. They make missed invalidations survivable. They make emergency flushes less scary because the system was already designed for cache entries to disappear.
But TTLs should be chosen with the error mode in mind.
A five-minute stale product description may be harmless. A five-minute stale permission decision may be unacceptable. A one-hour absence marker may be fine if it only suppresses repeated no-op work and is cleared by the create path.
The TTL is not just a performance setting. It is a correctness boundary.
Observability Is Part of the Design
A cache without metrics is a superstition.
At minimum, I want to know:
- hit rate
- miss rate
- error rate
- latency
- evictions or expirations
- size or key count
- fallback rate
- invalidation rate
The most useful cache metric is often not hit rate. It is fallback behavior. If the cache fails, does the system keep working? If the hit rate drops, do downstream dependencies absorb the load? If invalidation spikes, is that expected or is a writer misbehaving?
The cache should tell operators when it is helping and when it is merely present.
The Fallback Path Must Stay Healthy
The fallback path is production code.
If the cache normally handles 95 percent of reads, it is tempting to ignore the uncached path. That path may be slower, less tested, or underprovisioned. Then the cache has an incident and the fallback path collapses under traffic it has not seen in months.
A boring cache design keeps the fallback path honest:
- load test without the cache
- sample bypasses in production when safe
- alert on fallback latency
- keep source-of-truth reads efficient enough to survive cache loss
- document the emergency flush procedure
The cache is only optional if the fallback really works.
The Lesson
Clever caches often move complexity. Boring caches remove it.
They are exact where correctness needs exactness. They are bounded where memory or staleness matters. They are observable enough to prove they help. They degrade in a way the rest of the system understands.
The best cache does not make people ask, "What does this thing know?"
It makes people say, "If it is there, use it. If it is not, carry on."