Define what can be cached

Separate immutable assets, public content, and user-specific responses. Only cache data when the cache key and freshness policy are explicit enough to explain to another engineer.

Use a stable cache key

cacheKey = `product:${productId}:locale:${locale}:version:${schemaVersion}`

Keep authorization state out of a shared cache key unless the response is intentionally public. Private responses should use an explicit private caching policy.

Choose TTLs from business tolerance

  • Static assets: long TTL with immutable versioned URLs.
  • Public content: moderate TTL with targeted purge after publishing.
  • Highly volatile content: short TTL or explicit revalidation.
  • User-specific data: generally no shared edge cache.

Invalidate only what changed

Prefer targeted invalidation by content tag or resource identifier. Broad cache clears increase origin load and make the next request pay the full generation cost.

Verify the cache contract

Instrument cache status, origin latency, and invalidation events. During an incident, you should be able to explain whether a response came from cache, which version generated it, and when the cache was last refreshed.

Continue with observability

Use cache metrics alongside request logs so freshness and latency stay visible together.

Configure logs and alerts