Cache invalidation
A cache needs a freshness promise
Decide how old a value may be and what happens when that limit is exceeded. Faster reads are useful only while the result remains suitable for the task.
In this article
Different screens can tolerate different delays
A public list of office locations may remain useful for several minutes after an edit. A permission decision or available credit check can become unsafe immediately after a change. Giving both the same cache duration makes a technical convenience into an accidental business policy.
Begin with the action the reader will take. A stock indication on a catalogue can be approximate if checkout validates availability. A dispatch operation needs the authoritative reservation decision. The acceptable age depends on where the information is used, not simply which database table stores it.
Document that distinction in the interface as well as the backend. If a screen presents a delayed estimate as a confirmed quantity, the user cannot make the right decision even when the cache behaves exactly as configured.
Treat the cache as a copy
In a cache-aside arrangement, the application loads missing values from the source and stores them for later reads. The source remains responsible for the authoritative state. This simple pattern reduces repeated work, but it does not automatically keep every copy current.
Identify all copies involved. A browser, edge cache, application process and shared cache can each retain a response. Clearing one layer may leave another serving the old result.
- Request contextIdentify resource, tenant and required freshness
- Cached copyCheck scope, version and allowed age
- Authoritative readLoad current data when reuse is unsuitable
- ResponseReturn the value with an appropriate freshness policy
Understand the refill race
Suppose a reader loads revision 4 from the database. Before it stores that value in the cache, a writer commits revision 5 and deletes the cache entry. The reader then stores revision 4. Invalidation happened, yet stale data returned.
Deleting after the database commit avoids one common ordering mistake, but does not eliminate every concurrent race. Depending on the required guarantee, consider version checks, generation-based keys or bypassing the cache for critical reads. Each introduces its own coordination requirements.
A short expiry limits the duration of some stale values. It does not prove that a value is current at the moment a business decision is made.
Choose behaviour during failure
When the source is unavailable, some information can be served stale with a clear age indicator. Other operations should wait or fail. Decide this per use case rather than enabling stale fallback across the entire application.
Protect the source from a sudden wave of misses. Coalescing concurrent loads, limiting refresh work and spreading expiry times can help, but test their behaviour when the cache is empty. A warm-cache benchmark hides the most demanding recovery condition.
The design is ready when a maintainer can explain what a reader sees after a write, during a failed invalidation and after a cache restart. A high hit rate alone answers none of those questions.
Primary sources
Microsoft: cache-aside patternHTTP caching standardReferences checked 11 September 2026.