Cache-Control
Cache-Control is an HTTP header that controls caching behavior. Good caching improves speed and lowers TTFB; bad caching serves stale content.
Definition
Cache-Control is an HTTP response header that tells browsers and CDNs how to cache resources (max-age, s-maxage, stale-while-revalidate). Proper caching improves performance and reliability, while misconfiguration can serve stale content and delay updates.
Why it matters
- Dramatically improves TTFB and LCP — cache hits have near-zero latency, users see content in milliseconds
- Reduces server load — cache absorbs most requests, lowering origin pressure
- Improves Core Web Vitals — Google evaluates page speed, caching directly affects scores
- Reduces bandwidth costs — cached resources don't re-transfer, saving CDN fees
- Improves crawler efficiency — when Googlebot hits cache, origin load stays low
- Enables offline experience — combined with Service Worker for full offline caching
- Fault tolerance — stale-while-revalidate serves old content when origin is down
How to implement
- Static assets: use immutable + max-age=31536000 (1 year) with fingerprinted filenames
- HTML: use short TTL (max-age=0 or 60s) + stale-while-revalidate for freshness
- API responses: set based on data characteristics—long cache for static data, no-store for real-time
- Use s-maxage to control CDN caching separately from browser cache
- Add Vary: Accept-Encoding to properly cache compressed versions
- Use ETag or Last-Modified to support conditional requests (304 Not Modified)
- Test: check Response Headers and cache hit status in DevTools
Examples
http
# Static assets (fingerprinted JS/CSS/images)
Cache-Control: public, max-age=31536000, immutable
# immutable tells browser no revalidation needed, cache forever
# HTML documents (need to stay fresh)
Cache-Control: public, max-age=0, must-revalidate
# Or use SWR: serve cached first, update in background
Cache-Control: public, max-age=60, stale-while-revalidate=86400
# API responses (based on data characteristics)
# Static data (e.g., city list)
Cache-Control: public, max-age=86400, s-maxage=604800
# Real-time data (e.g., inventory)
Cache-Control: no-store
# CDN-specific (let CDN cache longer)
Cache-Control: public, max-age=60, s-maxage=31536000text
# public/_headers
# Default: all pages
/*
Cache-Control: public, max-age=0, must-revalidate
# Fingerprinted static assets
/assets/*
Cache-Control: public, max-age=31536000, immutable
# Images (can cache longer)
/*.webp
Cache-Control: public, max-age=2592000
/*.avif
Cache-Control: public, max-age=2592000
# API responses (no caching for sensitive data)
/api/user/*
Cache-Control: private, no-storeFAQ
Common questions about this term.