HTTP Caching, CDN Invalidation & Cache-Control Architecture Runbook
The definitive architectural guide to modern HTTP caching: deconstructing RFC 9111 Cache-Control directives, stale-while-revalidate background refreshes, cryptographic ETag validation, Surrogate-Key edge purging, and immutable asset fingerprinting for high-performance CDNs.
1. The Modern HTTP Caching Mental Model: Private vs. Shared Edge Caches
# Private Cache: Stored exclusively in the user's browser (contains PII / auth tokens)
HTTP/1.1 200 OK
Cache-Control: private, max-age=300, must-revalidate
Vary: Authorization, Cookie
# Shared Edge Cache: Cached by CDN edge nodes globally for all anonymous users
HTTP/1.1 200 OK
Cache-Control: public, max-age=3600, s-maxage=86400, stale-while-revalidate=604800
Surrogate-Key: product_catalog tenant_42
Age: 1420The s-maxage directive overrides max-age exclusively for shared CDN caches, while the Age header indicates how many seconds the response has resided in edge memory.
| Cache Category | Storage Location | Shared Across Users | Typical Stored Data | Copy |
|---|---|---|---|---|
| Browser Private Cache | Client device disk and memory | No (Single user only) | User profile, shopping cart, private dashboard | |
| CDN / Edge Cache | Global Points of Presence (PoPs) | Yes (Shared globally) | Static JS/CSS bundles, public marketing pages | |
| Forward Proxy Cache | Enterprise or ISP gateway network | Yes (Shared within network) | Frequently accessed intranet and public docs | |
| API Gateway Microcache | Kubernetes Ingress / Envoy / Nginx | Yes (Decouples origin DB) | High-throughput dynamic REST/GraphQL query responses |
2. Cache-Control Directives Deconstructed: Freshness, Revalidation & Stale Shields
# Maximum performance recipe for hashed static assets (/assets/main.a9f4c1.js)
HTTP/1.1 200 OK
Content-Type: application/javascript; charset=utf-8
Cache-Control: public, max-age=31536000, immutable
# HTML Root Recipe (index.html: must revalidate instantly on deploy)
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: no-cacheThe immutable token signals that the resource representation will never change under this URI, instructing modern browsers to skip conditional validation even when the user hits reload.
| Directive | Browser Meaning | CDN Edge Meaning | Recommended Use Case | Copy |
|---|---|---|---|---|
| no-store | Never store in memory or disk | Never cache under any circumstance | Banking endpoints, PCI-DSS data, auth tokens | |
| no-cache | Cache response, but revalidate before reuse | Must validate with origin before serving | Single Page Application index.html files | |
| max-age=N | Fresh for N seconds from generation | Fresh for N seconds unless s-maxage exists | Content assets, public documents, articles | |
| s-maxage=N | Ignored by browser private caches | Overrides max-age exclusively on CDNs | Tiered caching: 5m in browser, 24h at CDN edge | |
| must-revalidate | Never serve stale copy if origin is down | Strictly blocks serving expired content | Financial ledgers, regulatory audit trails | |
| stale-while-revalidate=N | Serve stale instant, background refresh | Async origin fetch while serving edge hit | High-traffic news feeds, e-commerce listings |
4. Enterprise Edge Invalidation: Surrogate-Keys & Cache Stampede Prevention
# Origin tags API response with relational entity IDs
HTTP/1.1 200 OK
Surrogate-Key: user_942 org_12 team_billing
Cache-Control: public, s-maxage=604800, stale-while-revalidate=86400
# When user_942 updates their profile, purge exclusively matching keys via API:
curl -X POST "https://api.fastly.com/service/SERVICE_ID/purge/user_942" \
-H "Fastly-Key: ${FASTLY_API_TOKEN}" \
-H "Accept: application/json"Purging by Surrogate-Key takes under 150ms globally and invalidates only affected user representations, leaving the rest of the edge cache completely warm.
| Purge Mechanism | Speed & Latency | Cache Cold Risk | Best Practice Scenario | Copy |
|---|---|---|---|---|
| Purge Everything (All) | 300ms - 5000ms global | Catastrophic (100% origin slam) | Emergency hotfix deployments only | |
| Single URL Purge | Under 100ms global | Low (Affects 1 route only) | Single article or static file update | |
| Surrogate-Keys / Tags | Under 150ms global | Minimal (Precision targeting) | E-commerce SKU, user profile, multi-tenant SaaS |
5. Production Deployment Recipes: The Zero-Cache / Infinite-Cache Duality
# Nginx production block implementing optimal caching headers
server {
listen 443 ssl http2;
server_name mayonlinetools.com;
# 1. Root HTML: Never cache statically, force revalidation
location = /index.html {
add_header Cache-Control "no-cache, must-revalidate";
add_header X-Content-Type-Options "nosniff";
}
# 2. Immutable assets: Versioned with content hash (/assets/chunk-[hash].js)
location ~* \.(?:js|css|woff2|webp|svg)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
access_log off;
}
}When a new release ships, index.html updates instantly with new hashed asset paths (e.g., chunk-b24.js), eliminating stale asset collisions completely.
| Asset Classification | Cache-Control Header | Validation Strategy | Deployment Safety Guarantee | Copy |
|---|---|---|---|---|
| SPA HTML Entrypoint | no-cache, must-revalidate | Always validates on visit | Instant deployment pickup; zero stale bundles | |
| Hashed Bundles (.js, .css) | public, max-age=31536000, immutable | Never validates (Permanent hit) | Infinite speed; cache busted via unique URL hash | |
| Dynamic User API (/api/me) | private, no-cache | Revalidates with token | Zero risk of shared proxy data leakage | |
| Static Logos & Favicon | public, max-age=86400, stale-while-revalidate=604800 | Edge cached with async background refresh | Smooth asset rotation with zero user-facing latency |
Related Free Online Tools
Put these techniques into practice immediately with our privacy-first browser utilities:
Audit live Cache-Control, ETag, and defensive HTTP security headers.
Inspect cache-busting query parameters and versioned asset URL routes.
Compress and serialize API payloads for optimal CDN edge caching.