Glossary

Vary

Vary is a response header listing the request headers whose values the response depended on. A cache uses it to decide whether a stored response may be reused for a new request: if the request differs on any listed header, the stored copy does not apply. Omitting it where the response really does vary is how one visitor's variant gets served to another — and listing headers that barely matter fragments the cache until it stores almost nothing useful.

What goes wrong without it

A response that differs by language, compression or origin is stored once and served to everyone, because the cache has no reason to think it should not be.

The classic case is a cross-origin response echoing the requesting origin: correct for every individual request and wrong the moment a cache sits in front of it.

The second is content negotiation, where a modern image format is served to a client that accepts it and then handed to one that does not.

Neither fails in development, because there is usually no shared cache in the path. Both appear the day a CDN is introduced.

What goes wrong with too much of it

Each listed header multiplies the number of stored variants, and the counts multiply together rather than adding.

Listing a header that is effectively unique per visitor — a full user agent string, a cookie — means almost every request is a miss.

A cache with a near-zero hit rate is a cache being paid for and not used, and the symptom looks like a CDN that does not work.

Which is why the rule is to list exactly what the response depends on: no fewer, and no more.

The values worth knowing

Accept-Encoding, on any response whose compression is negotiated — which most servers add automatically.

Origin, on any response whose cross-origin header is computed from the request rather than fixed.

Accept-Language, where content is negotiated by language rather than served on separate URLs.

Accept, where the format is negotiated — an image endpoint returning a modern format to clients that accept one.

Authorization, on any cacheable authenticated response, which is what stops a cache keying two different callers to one entry.

How it is observed

Responses echoing a specific origin are checked for it, because that pairing is the one with a data-separation consequence.

Caching directives are read alongside, since Vary only matters on a response a cache is permitted to store in the first place.

Whether a CDN is serving hits or misses is read from the edge's own status header, which is where an over-broad Vary shows up as a symptom.

The full variant space cannot be measured from outside; what is observable is the declaration.

Frequently asked questions

Do I need Vary if I have no CDN?
It matters much less, because browser caches keep responses to themselves. It becomes consequential the day any shared cache — CDN, reverse proxy, corporate proxy — enters the path.
Can I just put Vary: * to be safe?
That tells caches the response is effectively uncacheable. It is safe and it throws away caching entirely, which is a large price for avoiding one decision.
Why is my CDN hit rate almost zero?
A frequent cause is a Vary listing something near-unique per visitor, such as a full user agent or a cookie. Every request becomes its own variant.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website