Stage 4 · Provision
Cache Design Patterns
CDN Cache Keys
Vary headers, query normalization, surrogate keys, and origin shielding in Fastly and CloudFront.
Cache Key Anatomy
The CDN cache key determines which requests share a cached response. A well-designed cache key maximizes hit rate while ensuring correct content. The key typically includes the URL path, query parameters, and relevant headers.
Full cache key:
/api/products?category=electronics&sort=price&fbclid=abc123
├── Path: /api/products
├── Query: category=electronics&sort=price&fbclid=abc123
└── Headers: Vary: Accept-Encoding
Optimized cache key:
/api/products?category=electronics&sort=price
├── Removed tracking params (fbclid, utm_*, ref)
├── Normalized param order
└── Added encoding to keyRemove tracking parameters, normalize query order, and include relevant headers. This maximizes cache hits without serving wrong content.
Vary Headers
The Vary header tells the CDN which request headers to include in the cache key. Vary: Accept-Encoding caches separate responses for gzip and brotli. Vary: Authorization caches separate responses for different users.
# Cache different versions for different encodings
Vary: Accept-Encoding
# Cache different versions for different content types
Vary: Accept
# Cache different versions per user (careful — low hit rate)
Vary: Authorization
# Don't vary on anything (same response for all)
Cache-Control: public, max-age=3600Vary: Authorization creates a separate cache entry per user. This can drastically reduce hit rate. Only use it when responses genuinely differ per user.
Query Normalization
Before normalization:
/products?b=2&a=1&page=1&ref=home&fbclid=xyz
/products?a=1&b=2&page=1&ref=home&fbclid=xyz
→ Two different cache keys (same content!)
After normalization:
1. Remove tracking params: ref, fbclid, utm_*
2. Sort remaining params: a=1&b=2&page=1
3. Result: /products?a=1&b=2&page=1
→ One cache key (correct!)Query normalization ensures equivalent URLs share the same cache key. Sort parameters alphabetically, remove tracking parameters, and normalize values.
Surrogate Keys
Surrogate keys tag cached objects with labels that enable bulk invalidation. Instead of purging individual URLs, you purge all objects with a specific surrogate key. Fastly and Cloudflare support surrogate keys natively.
# Response with surrogate keys
HTTP/1.1 200 OK
Cache-Control: max-age=300
Surrogate-Key: product-123 category-electronics
# Purge all products in electronics category
POST /api/purge
Surrogate-Key: category-electronics
# Purge a specific product across all pages
POST /api/purge
Surrogate-Key: product-123Surrogate keys enable efficient cache invalidation. Tag responses with meaningful keys and purge by key when content changes.
Origin Shielding
Origin shielding adds a caching layer between edge nodes and the origin. When an edge node misses, it queries the shield instead of the origin. This reduces origin load from hundreds of simultaneous edge requests to a single shield request.
Cache Key Debugging
- CloudFront: x-cache header shows HitFromRefresh or HitFromOrigin.
- Fastly: x-served-by and x-cache headers show cache status.
- Debug headers: Enable debug mode to see the actual cache key.
- Logs: CDN access logs show the full cache key and hit/miss status.
Use curl -v to see cache headers. Check x-cache: Hit from cloudfront or x-cache: HIT. Compare the same URL with different query parameters to verify normalization.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.