Skip to content
Devgo

Cache invalidation

The process of removing or updating cached data when the source changes so reads don't get stale results. Famously one of the two hard problems in CS. Strategies: TTL, explicit delete, event-driven, versioned keys.

When to use
  • Whenever staleness after writes is unacceptable.
  • CDN/query caches with selective purge.
When not to
  • When TTL staleness is acceptable (simpler).
  • When invalidation logic is more complex than the feature.

Definition

Invalidation ensures a cache doesn't serve outdated data after a write. Approaches: TTL-based (eventually fresh), explicit delete on write, event-driven (CDC/events delete affected keys), and versioned/cache-busting keys.

Why it exists

A cache that never invalidates lies. Without invalidation, updates aren't visible; with naive invalidation you get races (write then delete can be reordered) and stampedes. Correct invalidation is subtle.

How it works

On a write, delete the cache key (better than updating — avoids races) and let the next read repopulate. For complex caches (, query caches) use surrogate keys/tags to purge groups. Event-driven invalidation listens to DB changes (CDC) to evict affected keys.

Scaling limits

Figuring out which keys to invalidate for a given write is hard for query/aggregate caches. Event-driven invalidation adds infra and lag. Aggressive invalidation causes high miss rates.

Cost shape

Extra writes/events per mutation. Blow-ups: invalidation storms and over-eviction causing low hit ratio.

Alternatives

  • TTL — Bounded staleness with no wiring, but not fresh on write.
  • Versioned keys — Atomic invalidation by bumping a version, but more keys.

Failure modes

  • Write-then-delete race leaving stale data.
  • Missing an affected key.
  • Stampede after invalidation without a read lock.

, , , ,