Cache Keys
A cache key is the derived identity of a stored response, built from method, URL, and selected request headers, and it decides when two requests may share a cache entry.
Definition
A cache key is the normalized value a cache uses to look up a stored representation, typically combining the request method, target URI, and the request headers named by Vary, so that requests with different semantics never collide.
Context and scope
Use it when designing any shared cache layer, from a CDN edge to an application-level Redis cache, because key design determines hit ratio, correctness, and poisoning risk.
Common misconceptions
- The full URL is always a safe cache key; it ignores content negotiation and auth context
- More key dimensions always improve correctness; they can collapse the hit ratio
- Query parameter order never matters; many caches treat it as significant
Anti-patterns
- Caching authenticated responses under a key that omits the tenant or user
- Adding every header to Vary, which makes almost every request unique
- Letting arbitrary query parameters create unbounded key cardinality
Related concepts
Related examples
Authoritative source
What a cache key contains
At minimum, a cache key is the request method plus the target URI. HTTP caches extend it with the request headers listed in the response’s Vary field, and with the response status when the cache stores more than one variant. Anything not in the key is assumed irrelevant, which is exactly where bugs appear.
How it works
A CDN receiving GET /products?page=1&sort=asc and GET /products?sort=asc&page=1 may treat those as two keys unless it normalizes query order. A response with Vary: Accept-Encoding tells the cache to keep gzip and Brotli variants separate. Vary: Accept-Language does the same per locale.
Application caches choose their own keys, often entity:tenant:version. The safest pattern is to include every dimension that changes the body and nothing more: tenant, locale, representation, and authorization scope where responses differ.
When to use it
Design keys explicitly for shared caches at the edge, for expensive computed fragments, and for multi-tenant services. For per-user data, either bypass shared caches or include the user identity and mark the response private. When a resource has many low-value parameter combinations, restrict which parameters participate in the key.
Trade-offs
Fine-grained keys preserve correctness but lower the hit ratio and increase storage. Coarse keys raise hits but risk serving one tenant’s data to another, which is a breach rather than a performance bug. Normalization helps hits but must not merge semantically different requests. Every added dimension also increases the purge surface.
Example and misconceptions
A storefront adds Vary: Accept-Encoding, Accept-Language and normalizes parameter order. Hit ratio rises because equivalent URLs now share entries. A later change adds a currency cookie without adding it to the key, and prices leak across regions.
The common misconception is that the URL uniquely identifies a response. It does not: headers, cookies, and auth context can change the body, so they must be represented in the key or explicitly excluded from caching.
Related concepts: HTTP Caching, Content Delivery Network, and Cache Invalidation.