HTTP caching is the standard mechanism of storing responses and reusing them for identical requests to cut latency, bandwidth, and server load.
It exists at multiple layers — from the browser (private cache) to CDNs and reverse proxies (shared caches) — and is controlled precisely by response headers.
The core is two phases: freshness and revalidation. During the fresh window (e.g. `Cache-Control: max-age=600`) the cache is used directly without any network request (fastest); once expired, the client sends `ETag`/`Last-Modified` as conditional headers to ask the server 'has it changed?' If not, a `304` avoids re-downloading the body. Key directives include `no-store` (don't store), `no-cache` (store but always revalidate), `private` (private cache only), `public` (shared caches allowed), `immutable`, and `stale-while-revalidate`.
Practical patterns matter: hashed static assets (app.9f3a.js) are cached essentially forever with `max-age=31536000, immutable`, while HTML that changes often uses `no-cache` to revalidate every time. A common incident is leaking personalized/authenticated responses to a shared cache (CDN) as `public`, exposing them to other users — so mark per-user responses `private`/`no-store` carefully. When you must update, combine CDN purges with filename versioning to prevent the 'stale content' problem.