Cache Key
A unique identifier generated from request attributes that determines whether requests can share a cached response. Typically derived from the URL and Host header, but can include other headers (via Vary), cookies, or query parameters depending on CDN configuration.
Full Explanation
The cache key is the unique identifier that a cache uses to decide whether an incoming request matches a stored response. The default cache key for most CDNs and proxies is built from the scheme (http/https), hostname, path, and query string. Two requests with the same cache key get the same cached response. Two requests with different cache keys are treated as completely separate resources.
The Vary header extends the cache key by adding request header values to it. If the response includes Vary: Accept-Encoding, the cache key also includes whatever the client sent in Accept-Encoding. So GET /style.css with Accept-Encoding: gzip and GET /style.css with Accept-Encoding: br produce different cache keys and get different cached entries.
Customizing cache keys is where things get powerful and dangerous. On the powerful side, you can strip tracking query parameters like utm_source and fbclid so that /page?utm_source=twitter and /page?utm_source=email share the same cache entry. You can also sort query parameters so ?a=1&b=2 and ?b=2&a=1 hit the same cache. On the dangerous side, getting the cache key wrong leads to cache poisoning (serving one user's content to another) or terrible hit ratios (caching the same content hundreds of times under different keys).
// Default cache key components
Request: GET https://cdn.example.com/products?id=42&ref=homepage
Cache key: https | cdn.example.com | /products | id=42&ref=homepage
// With Vary: Accept-Encoding, Accept-Language
Cache key: https | cdn.example.com | /products | id=42&ref=homepage | gzip | en-US
// After stripping tracking params (utm_*, ref, fbclid)
Cache key: https | cdn.example.com | /products | id=42
// Now ?ref=homepage and ?ref=twitter share the cached response
Interactive Animation
Examples
Here is a Varnish VCL example that normalizes cache keys by stripping tracking query parameters and sorting the remaining ones.
sub vcl_recv {
# Strip tracking query params from cache key
set req.url = regsuball(req.url, "(\?|&)(utm_[a-z]+|fbclid|gclid|ref)=[^&]*", "");
# Clean up leftover ? or &
set req.url = regsub(req.url, "\?&", "?");
set req.url = regsub(req.url, "\?$", "");
}
# These all resolve to the same cache key after normalization
curl https://cdn.example.com/page
curl https://cdn.example.com/page?utm_source=twitter
curl https://cdn.example.com/page?fbclid=abc123&utm_medium=social
# All three get the same cached response
Video Explanation
Frequently Asked Questions
A unique identifier generated from request attributes that determines whether requests can share a cached response. Typically derived from the URL and Host header, but can include other headers (via Vary), cookies, or query parameters depending on CDN configuration.
Here is a Varnish VCL example that normalizes cache keys by stripping tracking query parameters and sorting the remaining ones.
sub vcl_recv {
# Strip tracking query params from cache key
set req.url = regsuball(req.url, "(\?|&)(utm_[a-z]+|fbclid|gclid|ref)=[^&]*", "");
# Clean up leftover ? or &
set req.url = regsub(req.url, "\?&", "?");
set req.url = regsub(req.url, "\?$", "");
}
# These all resolve to the same cache key after normalization
curl https://cdn.example.com/page
curl https://cdn.example.com/page?utm_source=twitter
curl https://cdn.example.com/page?fbclid=abc123&utm_medium=social
# All three get the same cached response