When you build web apps that use caching-CDNs, reverse proxies, or even browser cache, the Vary header becomes one of, your best friends. It tells caches how to treat different versions of the same URL, so users always get the correct response.
Letβs break it down.
What Does the Vary Header Do?
A cache normally stores one version of a URL. But sometimes, your server returns different responses depending on headers like:
-
Accept-Encoding(gzip vs br) -
User-Agent(mobile vs desktop) -
Accept-Language(English vs Turkish) -
Authorization(logged-in vs guest) -
Origin(CORS decisions)
The Vary header says:
βIf this header changes, treat the response as a separate cache entry.β
Example:
Vary: Accept-Encoding
This tells the cache: βStore a gzip version and a br version separately, donβt mix them.β
Why the Vary Header Matters
1. Prevents Serving Wrong Content
Imagine your server returns Turkish content only when Accept-Language: tr is sent.
Without Vary: Accept-Language, the first cached TR version could be served to English users too. Disaster.
2. Helps with Device-Specific Views
If you send different HTML for mobile vs desktop:
Vary: User-Agent
Without it, desktop users might get mobile HTML.
3. Required for Some Security Features
Some servers vary behavior based on Origin.
Then you must add:
Vary: Origin
Otherwise a cached response may incorrectly allow or deny CORS requests.
Common Vary Header Use Cases
Gzip / Brotli Compression
Most common one:
Vary: Accept-Encoding
Needed so caches donβt serve Brotli to browsers that donβt support it.
Localization
Vary: Accept-Language
For language-specific pages.
CORS
Vary: Origin
If you send dynamic CORS headers.
Cookies / Auth
Be careful.
Vary: Cookie can kill cache efficiency because cookies are all unique.
But itβs valid when you must split cached pages between logged-in and guest users.
Examples
Nginx
nginxadd_header Vary Accept-Encoding;
Express.js
jsapp.use((req, res, next) => {
res.set("Vary", "Accept-Encoding");
next();
});
Go (net/http)
gow.Header().Add("Vary", "Accept-Encoding")
Best Practices
-
Keep
Varyheaders short. Donβt add unnecessary variations. -
Avoid
Vary: Cookieunless absolutely required. -
Always set
Vary: Accept-Encodingif you use gzip/brotli. -
If you use dynamic CORS, donβt forget
Vary: Origin.
Conclusion
The Vary header is tiny but powerful.
It keeps your caching layer smart, prevents content mismatches, and ensures users get the right version of your pages.
Use it correctly, and your app becomes faster and more reliable. Forget it, and youβll chase weird bugs for days.
Album of the blog:




