Two mechanisms quietly destroy more cache efficiency than everything else combined: cookies, which platforms treat as radioactive, and Vary, which multiplies cache entries per header value. Both exist for good reasons; both are usually misconfigured. This guide separates the legitimate uses from the shredders and gives you the audit for each.
Why cookies are treated as radioactive
CDNs handle cookies with extreme conservatism because they signal personalization: a response generated under a cookie might be user-specific, and caching it publicly is the canonical leak. The defaults that follow: many platforms skip caching entirely when a response carries Set-Cookie, and some bypass on request cookies for certain content types unless told otherwise. The conservatism is correct — and it means one stray cookie converts a cacheable estate into a pass-through proxy. The classic case: an analytics, consent or A/B cookie set server-side on every first visit, making every first visit uncacheable and, with Set-Cookie rules, un-storable — a marketing-tag decision quietly deleting your hit ratio, invisible until you segment measurements per the measurement guide.
Cookie rules: session vs noise
The fix is classifying cookies once and encoding the classes. Session-class cookies (login, cart, session ID) drive the bypass rules from the HTML guide: their presence means personal, skip cache both directions — enumerate them by name in the CDN rule, don't pattern-match broadly. Noise-class cookies (analytics IDs, consent state, campaign attribution) must be made irrelevant to caching: move their setting client-side (JS-set cookies never appear in Set-Cookie), and configure the edge to ignore them on requests — they stay out of the cache key (never key on cookies except a deliberate coarse dimension, per the cache-key guide) and their presence doesn't trigger bypass. The audit habit: grep origin responses for Set-Cookie on anonymous static and HTML paths — every hit is either a session boundary doing its job or a noise cookie shredding you; there is no third category.
Vary: the multiplication machine
Vary tells caches which request headers change the response — each distinct value combination of the named headers gets its own cache entry, which makes Vary a multiplication operator on your cache. Vary: Accept-Encoding multiplies by a handful (fine, and mostly platform-managed). Vary: User-Agent multiplies by the tens of thousands of UA strings in the wild — hit ratio effectively zero, the classic shredder, usually inherited from a device-detection library nobody audited. Vary: Cookie multiplies by every distinct cookie header — per-user cache entries at best, and some platforms respond by refusing to cache at all. Vary: * forbids caching outright. The rule: every header named in Vary must be low-cardinality after normalization, or the response shouldn't be cached — and if the origin emits high-cardinality Vary you can't remove at source, override or strip it at the edge deliberately, accepting that you're asserting the origin was wrong.
The legitimate Vary uses
Vary earns its keep in a few disciplined shapes. Encoding: Vary: Accept-Encoding is standard and safe — modern platforms normalize the header to its few meaningful values before keying, and compression variants are handled internally on most CDNs anyway (the per-platform behavior appears in the compression matrix). Negotiated formats: Vary: Accept where one URL serves, say, AVIF/WebP/JPEG by capability — again workable because platforms normalize to the format decision, the pattern the images guide relies on. Coarse custom dimensions: varying on a computed header your edge sets (X-Country-Group: EU|US|ROW, X-Device-Class: mobile|desktop) — you control cardinality because you minted the values, which is the correct rewrite of every Vary: User-Agent and Vary: Accept-Language in existence: normalize first at the edge, vary on the normalized result. The shape all three share: the varied dimension is enumerable on one hand, and you can name every value.
The audit for both
Both shredders are found the same way: from logs, not configuration. Pull a day of edge logs; for the cookie side, list paths where requests carried cookies or responses carried Set-Cookie, and reconcile against your session-class list — anything else is noise to relocate. For the Vary side, list distinct Vary values served per path and, for each varied header, count the distinct request values observed — the multiplication factor is right there, and any factor beyond low double digits on a cached path is your finding. Fix at origin where possible, override at edge where not, purge the affected paths, and re-measure a cache-lifetime later. Then make both checks permanent: the Set-Cookie-on-anonymous-paths grep and a Vary allowlist assertion belong in CI, because both shredders are one dependency upgrade away from returning — and both return silently.
