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.
