No-Vary-Search
Cache efficiency suffers when tracking parameters create separate entries for identical content. The No-Vary-Search response header declares which URL query parameters are irrelevant for cache matching, allowing caches and browsers to reuse responses across URLs differing only in ignored parameters.
Usage
By default, HTTP caches treat URLs with different query
strings as distinct resources. A response cached for
/results?q=shoes&utm_source=email is not reused for
/results?q=shoes&utm_source=social, even when the
server returns identical content for both. The
No-Vary-Search header changes this behavior by
telling caches which query parameters to ignore during
matching.
The header uses Structured Fields syntax. Three
directives control matching: key-order ignores
parameter ordering, params lists parameters to ignore
(or ignores all parameters when used as a boolean), and
except lists parameters still affecting matching while
ignoring everything else.
The most common use case is analytics and tracking
parameters. Parameters like utm_source, utm_medium,
utm_campaign, fbclid, and gclid do not change
the server response but create separate cache entries
for every combination. Declaring these in
No-Vary-Search allows caches to serve a single
response regardless of tracking parameter variations.
The header integrates with the
Speculation Rules API for
prefetch and prerender matching. When a page is
prefetched with one set of query parameters and the
user navigates with a different set, the browser checks
No-Vary-Search to determine whether the prefetched
response is reusable. Speculation rules support an
expects_no_vary_search field hinting at the expected
header value before the prefetch response
arrives, allowing the browser to decide whether to
wait for an in-flight prefetch or start a new request.
Directives
key-order
The key-order directive tells caches to ignore the
order of query parameters. URLs with the same
parameters in a different sequence match the same
cached response. Parameter names and values must still
match.
params
The params directive controls which parameters are
ignored during cache matching. Used as a list
(params=("utm_source" "utm_medium")), only the
listed parameters are ignored while other parameters
still affect matching. Chromium additionally accepts
a boolean form (params) ignoring all query
parameters so the cache matches on the URL path
alone, a form the draft rejects.
except
The except directive lists parameters remaining
significant for cache matching. All other parameters
are ignored. This is the
inverse approach: instead of listing parameters to
ignore, list only the parameters mattering for cache.
The draft defines except as standalone and forbids
combining except with params in any form, while
Chromium requires the boolean params directive
alongside except.
Example
Ignoring analytics parameters. Responses are reused across different UTM tracking combinations, improving cache hit rates for marketing campaigns.
No-Vary-Search: params=("utm_source" "utm_medium" "utm_campaign" "utm_content" "utm_term")
Ignoring parameter order. The cache treats
?a=1&b=2&c=3 and ?b=2&a=1&c=3 as the same
resource.
No-Vary-Search: key-order
Ignoring all parameters except a product identifier.
Only the id parameter affects which cached response
is returned. All other parameters (sorting, filtering,
tracking) are irrelevant.
No-Vary-Search: params, except=("id")
The draft's form of the same policy names the
significant parameter with a standalone except
list, the shape the specification validates.
No-Vary-Search: except=("id")
Ignoring all query parameters entirely. The cache
matches on the URL path alone, treating
/page?anything=here the same as /page.
No-Vary-Search: params
Combining key-order with an except list. Parameter
order is ignored, and only the q search term
affects cache matching.
No-Vary-Search: key-order, params, except=("q")
A speculation rules script using
expects_no_vary_search to indicate prefetched
pages ignore tracking parameters. The browser
reuses a prefetch even when the navigation URL has
different UTM values.
{
"prefetch": [{
"source": "list",
"urls": ["/results?q=shoes"],
"expects_no_vary_search":
"params=(\"utm_source\" \"utm_medium\")"
}]
}
See also
- The No-Vary-Search HTTP Caching Extension (IETF Draft)
- Speculation Rules API (MDN)
- Speculation Rules
- Sec-Purpose
- Vary
- Structured Fields
- Caching
- HTTP headers