Name the scope of the cached value

A cache key is a statement about equivalence. If two requests share a key, the system claims they may receive the same value. Include every dimension that changes the response: tenant, user role, language, currency, feature state, and relevant query parameters.

Public caches must never store personalized or authorization-dependent responses unless the edge key and cache-control policy have been designed for that exact use.

Prefer bounded staleness

Time-to-live is not a substitute for invalidation, but it limits the damage when invalidation fails. Combine event-driven deletion for important writes with a maximum lifetime and a version namespace for large schema changes.

Prevent stampedes by allowing one process to refresh while others briefly serve the previous value, or by using a short lock with a strict timeout.

  • Document key format and ownership.
  • Add random jitter to large groups of expirations.
  • Do not hold a cache lock while making slow optional calls.
  • Define behavior when the cache is unavailable.

Measure correctness as well as hit rate

A high hit rate can hide incorrect sharing. Log cache outcome, key namespace, age, and refresh reason without logging sensitive key material. Compare a sample of cached responses with a fresh calculation in a safe environment.

Treat the cache as disposable. The application should recover if the entire cache is flushed, even if performance is temporarily reduced.

Verification checkpoint

Request the same resource as different users, tenants, languages, and permissions; inspect headers and values to prove that no cache key crosses an isolation boundary.