DevKits

HTTP Caching Cheat Sheet

Every Cache-Control directive, plus Expires, ETag, Vary — with correct examples and the pitfalls that bite most developers.

Cache-Control Directives

DirectiveWhat it doesExampleNote
max-age=<seconds>Response stays fresh for <seconds> from the response date. Relative, no clock drift.Cache-Control: max-age=3600Always preferred over Expires.
s-maxage=<seconds>Shared cache (CDN) max-age. Overrides max-age for CDNs. Browsers ignore this.Cache-Control: s-maxage=60, max-age=3600CDN caches 1 min; browser caches 1 hour.
publicAny cache (browser + CDN) may store the response.Cache-Control: public, max-age=31536000, immutableDefault for static assets.
privateOnly the user's browser cache. CDNs MUST NOT store.Cache-Control: private, max-age=300User-specific responses.
no-cacheCache may store, but MUST revalidate (conditional GET) before using. Does NOT mean don&apos;t cache.Cache-Control: no-cacheTop HTTP mistake: confusing no-cache with no-store.
no-storeDon&apos;t store the response at all. Every request hits the origin.Cache-Control: no-storeBank balances, auth tokens, real-time data.
immutableOn page reload, skip revalidation — the resource hasn&apos;t changed. For hash-named static assets.Cache-Control: public, max-age=31536000, immutablePairs with content-hash filenames.
must-revalidateBefore reusing a stale response, the cache MUST revalidate with the origin.Cache-Control: max-age=3600, must-revalidateStricter than the default revalidation behaviour.
stale-while-revalidateServe stale content while asynchronously revalidating in the background.Cache-Control: max-age=3600, stale-while-revalidate=600Great UX for APIs that change infrequently.
stale-if-errorServe stale content if the origin server is unreachable.Cache-Control: max-age=3600, stale-if-error=86400Graceful degradation for CDNs.

Other Caching Headers

Expires

Expires: Thu, 01 Dec 2025 16:00:00 GMT

Absolute wall-clock expiry. Superseded by Cache-Control max-age. Clock drift makes it unreliable.

ETag

ETag: "33a64df5"

Opaque version identifier. Sent back as If-None-Match for conditional GETs. Server returns 304 Not Modified if unchanged.

Last-Modified

Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT

Date-based version. Prefer ETag when both available.

Age

Age: 24

How many seconds the response has been in a shared cache. Set by CDNs. Used to compute remaining freshness.

Vary

Vary: Accept-Encoding, Origin

Tells caches to partition the response by request header values. Critical for CORS and compression.

Pro tip: For static assets with content-hash filenames (main.abc123.js), use Cache-Control: public, max-age=31536000, immutable. Immutable tells the browser to skip revalidation on reload — zero requests to your server. See the full HTTP Caching Guide for in-depth explanations of each directive.