Build a CDN (13 scenes)
Scene 08 · Cache key and Vary — when 'same URL' isn't
The cache key defaults to method + URL; Vary multiplies it by request-header values — Vary: User-Agent shatters one URL into thousands.
Previously

Purge invalidates entries — but what determines which entries are matches in the first place? The cache key, and the Vary header that quietly multiplies it.

Scene 08
Cache key and Vary — when 'same URL' isn't
Diagram
Two requests for /index.html — when does the cache treat them as the same? What it uses to decide is the cache key. The URL column on the left is the one URL; the grid on the right shows every distinct cached entry that URL has produced under the current Vary axes (top strip), with one cell per (axis-value, axis-value, …) tuple. The bottom gauges read the resulting hit ratio and memory used.
Vary:Encoding×3LanguageUser-AgentCookieURL/index.html1 URLENTRIES PER URL3distinct cached entriesCACHED ENTRIES · 2D KEY SPACEshowing 3 of 3gzipbridentityHIT RATIO95%0%100%MEMORY USED0.15 MB0cap 256 MB
Vary: Accept-Encoding — entries per URL = 3.
cache key = method + URLVary axes multiply the key1 URL → 3 entrieshit ratio · 95%memory used
Vary: Accept-Encoding only. Three entries per URL (gzip / br / identity). As requests pour in, the hit-ratio gauge climbs and memory stays low — every browser's encoding lands on one of the three cached entries.
Implementation
Edge.compute_cache_key
URL is the default; Vary axes append request-header values
1def compute_cache_key(req, vary):
2 # the default identity: method + full URL
3 key = req.method + ' ' + req.url
4 # Vary tells the cache to also key on these headers
5 for axis in vary:
6 v = req.headers.get(axis, '')
7 key += '|' + axis + '=' + v
8 return hash(key)
Edge.vary_axes_for(url)
the axes the origin asked the cache to key on
1def vary_axes_for(url):
2 resp = cache.peek_response(url)
3 # parsed from the origin's `Vary:` response header
4 return resp.headers.get('Vary', '').split(',')
5 # e.g. ['Accept-Encoding'] -> 3 entries
6 # ['Accept-Encoding','Accept-Language'] -> 24
7 # [...,'User-Agent'] -> ~5000+