The HTTP Vary header tells caches which request headers may affect a response, so a cache doesn't serve a browser's HTML to an API client asking for JSON. Cloudflare cites an external analysis of over 120 million responses across nearly 50,000 popular sites finding almost 3,000 varying on four or more fields, some on 10, 23, or even 47. Vary is correct but, taken literally, can make caching nearly worthless: ten values across three fields already create up to 1,000 variants, and headers like Accept-Language can differ in order or formatting while meaning the same thing to the origin.

The result is a cache that is 'perfectly correct and almost permanently cold': byte-identical responses scatter across many barely reused entries, evicting each other and pushing more requests back to origin. Existing workarounds, bypassing cache entirely, duplicating negotiation logic in a Worker, or narrow features like Vary for images, each gave up caching, duplicated application logic, or covered only one case.

Cache Rules now let the origin keep declaring Vary headers while a rule setting decides, per header, whether to normalize values into a small equivalence set, pass exact values through, or bypass caching for unpredictable headers. Two Accept-Language requests, en-US, fr;q=0.8 and fr;q=0.8, en-GB, both preferring English, can now share one cached entry under normalize instead of becoming two variants, while a header that must vary exactly can use passthrough. It's available today on Free through Enterprise plans.

Separate what varies from how much variation counts

Normalizing Accept and Accept-Language by sorting on quality value and stripping to a configured set of formats collapses requests that are byte-different but semantically identical into one entry.

Making the normalize/passthrough/bypass choice per header, not globally, lets an operator treat Cookie as unbounded (bypass) while treating Accept-Language as a small closed set (normalize).

Forwarding the normalized header value to the origin, not just using it for the cache key, keeps the origin's response selection aligned with which cache variant it gets stored as.

Vary: * still always bypasses cache, since it can signal factors outside the HTTP message, like client IP, drove the response, which no header-level rule can safely normalize.

When a correctness mechanism explodes into combinatorial waste, find where you're treating 'different bytes' and 'different meaning' as the same thing, and give the operator a separate knob for each.

Cloudflare says it is evaluating whether ideas from the expired IETF Availability Hints draft could let origins describe their supported representations directly, reducing the manual work of configuring which formats and languages a Cache Rule should normalize. The post frames the current normalize/passthrough/bypass split as filling a gap between existing options (full bypass, custom cache keys, or Worker-based negotiation logic) rather than as a final design.

FOLLOW THE EVIDENCE

The sources

  1. We just shipped support for the ugliest part of HTTP: Vary blog.cloudflare.com