Vary Response Header
The Vary header lists request headers that change the representation, letting shared caches store multiple variants and preventing a compressed response from reaching the wrong client.
Definition
Vary declares which request headers participate in cache key selection. A cache stores one entry per combination of values of the listed headers, and a request must match a stored variant exactly to be served from cache. It is the mechanism that makes content negotiation, encoding selection, and device-specific responses cache-safe.
Context and scope
Required when responses differ by Accept-Encoding, Accept-Language, or custom headers such as device class or experiment buckets. CDNs honor it for shared caching; browsers include it in the HTTP cache key.
Common misconceptions
- Vary is only for CDNs — the browser HTTP cache keys on it as well
- More Vary headers make caching smarter — each added dimension multiplies cache entries and slashes hit ratio
- Vary on a standard header is enough — custom headers must actually be sent by clients or variants never match
Anti-patterns
- Serving encoded responses without Vary: Accept-Encoding and poisoning caches for clients lacking the decoder
- Varying on high-entropy headers such as User-Agent, fragmenting the cache into near-zero-hit shards
- Normalizing custom headers inconsistently between cache key and origin, causing variant mismatch loops
Related concepts
Related examples
Authoritative source
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Vary
What it is
When the same URL can return different bodies depending on request headers, a cache needs to know which dimensions matter. Vary enumerates them. A response that varies on Accept-Encoding and Accept-Language is stored once per observed combination, and lookups match on the same combination.
How it works
The cache computes a secondary key from the listed request headers at store time and at lookup time. Missing a match, it forwards the request and stores another variant. Wildcard behavior exists for cache-control extensions, but practical Vary is explicit header names. Too many dimensions explode the key space.
When to use it
Any endpoint that personalizes by header: language negotiation, encoding negotiation, cookie-gated experiments, or device classes. Prefer coarse buckets over raw values — normalize mobile versus desktop instead of varying on full User-Agent strings.
Pitfalls
Forgetting Vary on Accept-Encoding when enabling compression is a classic outage: brotli bodies reach gzip-only clients. Header normalization must be identical at every cache layer or requests thrash between variants. CDNs with surrogate keys can decouple grouping from Vary when header dimensions get unwieldy.