←Back to Guides
โšกWeb Performanceโฑ๏ธ 17 min read•Updated October 2026

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.

#HTTP Caching#CDN#Cache-Control#Performance#ETag#Cloudflare#Fastly#Nginx

1. The Modern HTTP Caching Mental Model: Private vs. Shared Edge Caches

Under the IETF RFC 9111 HTTP Caching specification, caches fall into two distinct operational classes: Private Caches (dedicated to a single user inside browser storage or mobile client devices) and Shared Caches (positioned between the client and origin server, including Cloudflare, Fastly, AWS CloudFront, and corporate reverse proxies). A sound caching strategy demands explicit directive targeting to prevent sensitive authenticated user data from leaking into public edge nodes.
Differentiating Private vs Public Caching Headers
# 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: 1420

The 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 CategoryStorage LocationShared Across UsersTypical Stored DataCopy
Browser Private CacheClient device disk and memoryNo (Single user only)User profile, shopping cart, private dashboard
CDN / Edge CacheGlobal Points of Presence (PoPs)Yes (Shared globally)Static JS/CSS bundles, public marketing pages
Forward Proxy CacheEnterprise or ISP gateway networkYes (Shared within network)Frequently accessed intranet and public docs
API Gateway MicrocacheKubernetes Ingress / Envoy / NginxYes (Decouples origin DB)High-throughput dynamic REST/GraphQL query responses

2. Cache-Control Directives Deconstructed: Freshness, Revalidation & Stale Shields

The Cache-Control header is not a simple boolean switch; it is a multi-token declarative grammar governing response lifetimes, validation triggers, and fallback behaviors during origin degradation. Confusing no-cache with no-store is among the most widespread and costly security and performance misconfigurations in modern web development.
The Immutable Fingerprinted Asset Pattern
# 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-cache

The 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.

DirectiveBrowser MeaningCDN Edge MeaningRecommended Use CaseCopy
no-storeNever store in memory or diskNever cache under any circumstanceBanking endpoints, PCI-DSS data, auth tokens
no-cacheCache response, but revalidate before reuseMust validate with origin before servingSingle Page Application index.html files
max-age=NFresh for N seconds from generationFresh for N seconds unless s-maxage existsContent assets, public documents, articles
s-maxage=NIgnored by browser private cachesOverrides max-age exclusively on CDNsTiered caching: 5m in browser, 24h at CDN edge
must-revalidateNever serve stale copy if origin is downStrictly blocks serving expired contentFinancial ledgers, regulatory audit trails
stale-while-revalidate=NServe stale instant, background refreshAsync origin fetch while serving edge hitHigh-traffic news feeds, e-commerce listings

3. Cryptographic Validation: Strong vs. Weak ETags & 304 Not Modified

When a cached representation exceeds its freshness lifetime (max-age expired), the client must revalidate the asset with the origin server before serving it. Conditional HTTP requests allow the server to verify whether the underlying entity has changed using cryptographic entity tags (ETags) or modification timestamps, transferring zero payload bytes on a match.
Conditional Validation Wire Exchange (304 Not Modified)
# 1. Client sends conditional request with stored ETag
GET /api/v1/pricing HTTP/1.1
Host: api.mayonlinetools.com
If-None-Match: "e29-6238ab20"
If-Modified-Since: Tue, 20 Oct 2026 14:00:00 GMT

# 2. Server detects matching hash and returns empty 304 response
HTTP/1.1 304 Not Modified
ETag: "e29-6238ab20"
Cache-Control: public, max-age=600
Content-Length: 0

A 304 response sends zero response body, cutting bandwidth consumption by over 99% while renewing the client freshness clock.

Validator TypeFormat ExampleComparison SemanticsServer OverheadCopy
Strong ETag"d41d8cd98f00b204e980"Byte-for-byte exact identity matchHigh (Requires full hash computation)
Weak ETagW/"6238ab-gzip"Semantically equivalent contentLow (Can use file mtime and inode size)
Last-ModifiedWed, 21 Oct 2026 12:00:00 GMTTimestamp resolution (1-second precision)Minimal (Stat call on disk filesystem)

4. Enterprise Edge Invalidation: Surrogate-Keys & Cache Stampede Prevention

Global CDNs like Cloudflare, Fastly, and CloudFront cache millions of representations across distributed Points of Presence (PoPs). Relying purely on URL-based purging is brittle and slow for relational data. Enterprise architectures leverage Surrogate-Keys (Cache-Tags) to link hundreds of distinct API responses to a single entity, allowing instantaneous cluster-wide invalidation upon mutation.
Fastly & Cloudflare Surrogate-Key Header Header Implementation
# 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 MechanismSpeed & LatencyCache Cold RiskBest Practice ScenarioCopy
Purge Everything (All)300ms - 5000ms globalCatastrophic (100% origin slam)Emergency hotfix deployments only
Single URL PurgeUnder 100ms globalLow (Affects 1 route only)Single article or static file update
Surrogate-Keys / TagsUnder 150ms globalMinimal (Precision targeting)E-commerce SKU, user profile, multi-tenant SaaS

5. Production Deployment Recipes: The Zero-Cache / Infinite-Cache Duality

A robust production frontend architecture relies on the classic web performance duality: cache HTML entrypoints with zero persistence (no-cache) and cache all referenced sub-resources (JS, CSS, images, fonts) with immutable infinite lifetimes (31536000 seconds) using content-based cryptographic filename hashing.
Definitive Nginx Production Caching Configuration
# 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 ClassificationCache-Control HeaderValidation StrategyDeployment Safety GuaranteeCopy
SPA HTML Entrypointno-cache, must-revalidateAlways validates on visitInstant deployment pickup; zero stale bundles
Hashed Bundles (.js, .css)public, max-age=31536000, immutableNever validates (Permanent hit)Infinite speed; cache busted via unique URL hash
Dynamic User API (/api/me)private, no-cacheRevalidates with tokenZero risk of shared proxy data leakage
Static Logos & Faviconpublic, max-age=86400, stale-while-revalidate=604800Edge cached with async background refreshSmooth asset rotation with zero user-facing latency

๐ŸŽ“Explore More Guides

โœจ