Vary Header Handling¶
The Vary response header tells caches which request headers affect the
response content. Relaycache uses it to produce per-variant cache keys.
Cache key construction¶
The base cache key is METHOD:path?query. When the origin responds with a
Vary header, Relaycache extends the key with the values of the named request
headers:
Base key: GET:/v2/library/nginx/manifests/latest
Vary: Accept
Request Accept: application/vnd.oci.image.manifest.v1+json
Final key: GET:/v2/library/nginx/manifests/latest[accept=application/vnd.oci.image.manifest.v1+json]
Different Accept values produce different cache entries, each with their
own blob on disk.
Special cases¶
Vary: *¶
The response must not be stored. Vary: * means “every request is unique”
— the origin is opting out of caching entirely. Relaycache respects this and
passes the response through without storing it.
Vary: Accept-Encoding¶
Handled normally. Different encodings produce separate cache entries:
GET:/file[accept-encoding=gzip] → blob A (compressed)
GET:/file[accept-encoding=identity] → blob B (uncompressed)
Key lookup — two-phase approach¶
There is a bootstrapping problem: to compute the Vary-extended key, we need to know which headers the origin varies on — but we only learn that from a cached entry’s stored headers.
Relaycache solves this with a two-phase lookup:
1. Look up base_key in moka
→ If found: read Vary from stored headers
compute refined_key = vary_cache_key(base_key, request, entry.headers)
if refined_key ≠ base_key: look up refined_key in moka
→ If not found: proceed with base_key (cache miss)
2. Use the result of phase 2 (or phase 1 if no refinement needed)
On the first ever request for a URL, there is no cached entry so the base
key is used. The origin’s response includes Vary, which is stored in the
entry. On subsequent requests, the Vary dimensions are available and the
refined key is used.