HTTP Caching: Complete Guide
HTTP caching strategies: Cache-Control directives, ETag/Last-Modified validation, CDN caching, stale-while-revalidate, and browser cache behavior.
HTTP caching strategies: Cache-Control directives, ETag/Last-Modified validation, CDN caching, stale-while-revalidate, and browser cache behavior.
A guide to HTTP caching directives and validation: Cache-Control values such as max-age, no-cache, no-store, private, public and immutable, and the validators ETag and Last-Modified, each with an example and notes on when it applies.
| Directive | Type | Description | Example | Notes |
|---|---|---|---|---|
| max-age=<seconds> | Freshness | How long the resource is considered fresh from the time of the request | Cache-Control: max-age=31536000 (1 year, for immutable assets) | Relative to request time; use long values for versioned static assets |
| s-maxage=<seconds> | Freshness (shared caches) | Like max-age but only for shared caches (CDNs), overrides max-age for shared caches | Cache-Control: s-maxage=3600, max-age=0 | CDNs respect s-maxage; browsers ignore it and use max-age |
| no-cache | Revalidation | Resource can be cached but must revalidate with origin server before use | Cache-Control: no-cache | Does NOT mean 'don't cache' — it means 'check with server first' |
| no-store | No caching | Do not store in any cache (browser, CDN, proxy) | Cache-Control: no-store | Use for sensitive data (banking, personal info) or highly dynamic content |
| private | Cache scope | Only cacheable by browser (private cache), not by CDNs/proxies | Cache-Control: private, max-age=3600 | Default for authenticated responses; use public for CDN-cached content |
| public | Cache scope | Cacheable by any cache including shared CDNs and proxies | Cache-Control: public, max-age=86400 | Required for CDN caching of content behind auth (with care) |
| must-revalidate | Revalidation | Once stale, the cached response cannot be used without successful revalidation | Cache-Control: max-age=3600, must-revalidate | Prevents serving stale content even when offline |
| stale-while-revalidate | Stale handling | Serve stale content while fetching fresh version in background | Cache-Control: max-age=3600, stale-while-revalidate=86400 | Improves perceived performance; user gets instant response, fresh content loads async |
| stale-if-error | Error fallback | Serve stale content if origin server returns 5xx error | Cache-Control: stale-if-error=604800 | Graceful degradation during origin outages; use with monitoring |
| immutable | Freshness optimization | Resource will never change; browser skips revalidation checks even on user reload | Cache-Control: max-age=31536000, immutable | Only for versioned assets (app.abc123.js); prevents unnecessary revalidation on reload |
| Mechanism | Header | Description | Example | Notes |
|---|---|---|---|---|
| ETag | ETag: "abc123" | Opaque identifier for a specific version of a resource, compared via If-None-Match | Client sends If-None-Match: "abc123"; server responds 304 Not Modified if unchanged | Strong ETags guarantee byte-for-byte identity; weak ETags (W/) allow semantic equivalence |
| Last-Modified | Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT | Timestamp of last modification, compared via If-Modified-Since | Client sends If-Modified-Since: <date>; server responds 304 if not modified | 1-second resolution; ETag is more precise and preferred for programmatic use |
The shape of this dataset, read from the data itself: every column, its type and a real value. Agents can use this to plan a query without fetching the whole document.
| Section | Field | Type | Example |
|---|---|---|---|
| directives | directive | string | max-age=<seconds> |
| directives | type | string | Freshness |
| directives | description | string | How long the resource is considered fresh from … |
| directives | example | string | Cache-Control: max-age=31536000 (1 year, for im… |
| directives | notes | string | Relative to request time; use long values for v… |
| validation | mechanism | string | ETag |
| validation | header | string | ETag: "abc123" |
| validation | description | string | Opaque identifier for a specific version of a r… |
| validation | example | string | Client sends If-None-Match: "abc123"; server re… |
| validation | notes | string | Strong ETags guarantee byte-for-byte identity; … |
The static files contain the same reference rows as the API, with no API rate limit. Live metadata, such as view counts, may differ. Use the API for content negotiation; use the static files for a cacheable snapshot.
curl "https://yjtoon.yunusemrevurgun.com/api/dataset/http-caching-guide?format=toon"
const res = await fetch( "https://yjtoon.yunusemrevurgun.com/static-data/dataset/http-caching-guide.toon" ); const toon = await res.text();
Rate limit: 120 requests per minute per IP, no key and no signup. API reference →