Stage 4 · Provision
Data Systems at Scale
Cache Hierarchies
Browser, CDN, edge, Redis, and application caches — layering caches for maximum performance.
Cache Layer Overview
A cache hierarchy places multiple caching layers between the client and the origin server. Each layer is progressively larger and slower. The goal is to serve as many requests as possible from the fastest layer, falling through to slower layers only on cache misses.
Client Request
│
▼
L1: Browser Cache ── 0ms, 10MB
│ miss
▼
L2: CDN Cache ── 1-10ms, TB per edge node
│ miss
▼
L3: Edge Cache ── 10-50ms, GB per region
│ miss
▼
L4: Application Cache ── 0.5ms, 100GB cluster (Redis)
│ miss
▼
L5: Database ── 5-50ms, unlimitedEach layer filters out a portion of requests. A typical distribution: 30% served from browser cache, 50% from CDN, 15% from Redis, 5% from database.
Browser Cache
Browser caching stores responses locally on the user's device. Subsequent requests for the same resource are served from disk without any network call. This is the fastest cache layer and the most important for web performance.
# Cache for 1 hour, revalidate before using
Cache-Control: max-age=3600, must-revalidate
# Cache for 1 year (immutable assets with content hash)
Cache-Control: max-age=31536000, immutable
# Never cache
Cache-Control: no-store
# Revalidate with server
ETag: "abc123"
If-None-Match: "abc123"
# Server returns 304 Not Modified if unchangedUse immutable caching for assets with content hashes in filenames (main.a1b2c3.js). Use short TTLs for API responses that change frequently.
CDN Cache
CDN edge nodes cache content at locations close to users. When a user requests content, the CDN serves it from the nearest edge node instead of the origin. This reduces latency and offloads the origin server. CloudFront, Fastly, and Cloudflare are major CDN providers.
Edge Cache
Edge caches (Cloudflare Workers, Fastly Compute, Lambda@Edge) run code at CDN edge nodes. They can dynamically generate cached responses, perform A/B testing, and transform content before caching. This moves application logic closer to users.
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const cache = caches.default
let response = await cache.match(request)
if (response) return response // Cache hit
response = await fetch(request) // Cache miss — fetch from origin
// Cache for 5 minutes
const headers = new Headers(response.headers)
headers.set('Cache-Control', 'public, max-age=300')
return new Response(response.body, {
status: response.status,
headers
})
}Edge workers can implement custom caching logic at the CDN layer. This is useful for personalized content that still benefits from edge caching.
Application Cache (Redis)
Redis sits between the application and the database. It provides sub-millisecond reads for hot data. Redis Cluster distributes data across multiple nodes for horizontal scaling. Use Redis for session data, API responses, and computed results.
Local In-Process Cache
Local caches (Caffeine, Guava) run in the same JVM as the application. They provide nanosecond access but are limited to a single instance. Use them for configuration, feature flags, and data that changes infrequently. Combine with Redis for a two-tier cache.
When data changes, it must be invalidated across all cache layers. A stale CDN cache can serve old data even after Redis is updated. Design invalidation strategies that account for every layer.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.