Mastering HTTP Caching: How Browsers Store and Validate Resources
This article explains the fundamentals of HTTP caching, covering the structure of HTTP messages, the two main cache strategies—strong caching and validation caching—the relevant response headers such as Expires, Cache-Control, Last-Modified, and ETag, and provides practical guidelines for effective cache implementation in web development.
Introduction
HTTP caching improves web performance by allowing browsers to reuse previously fetched resources. The mechanism is governed by response headers that tell the browser whether a cached entry can be used directly (strong cache) or must be validated with the server (conditional cache).
Cache Types
Two categories:
Strong (forced) cache : The browser serves the cached response without contacting the server as long as the entry has not expired.
Conditional (validation) cache : The browser sends a validator (Last‑Modified/If‑Modified‑Since or ETag/If‑None‑Match) to the server; the server replies 304 Not Modified if the resource is unchanged.
Strong Cache
The server provides expiration information via Expires (HTTP/1.0) or, more commonly, Cache‑Control (HTTP/1.1). The latter is preferred because it avoids client‑clock drift.
Cache-Control: private
Cache-Control: public
Cache-Control: max-age=31536000
Cache-Control: no-cache
Cache-Control: no-store max-agespecifies the lifetime in seconds. Example: a response with Cache-Control: max-age=31536000 is considered fresh for one year; during that period the browser returns the resource from its cache without any network request.
When the freshness period expires, the browser falls back to validation caching.
Conditional Cache
On the first request the server includes a validator: Last-Modified header with the resource’s modification timestamp. Etag header with an opaque identifier generated by the server.
Subsequent requests include the corresponding conditional headers: If-Modified-Since (uses the timestamp). If-None-Match (uses the ETag).
The server compares the validator with the current state of the resource:
If the resource has changed, it returns 200 OK with the full body.
If unchanged, it returns 304 Not Modified with no body, allowing the browser to reuse the cached copy.
Validator Details
Last‑Modified / If‑Modified‑Since
The server sends Last-Modified: Tue, 12 Apr 2026 08:00:00 GMT. The client later sends If-Modified-Since: Tue, 12 Apr 2026 08:00:00 GMT. If the resource’s modification time is later than the supplied timestamp, the server returns 200; otherwise 304.
Etag / If‑None‑Match
The server sends Etag: "a1b2c3d4". The client sends If-None-Match: "a1b2c3d4". A mismatch triggers 200; a match triggers 304. ETag validation has higher priority than Last‑Modified.
Requests That Are Not Cached
Responses containing Cache-Control: no-cache, Pragma: no-cache, or Cache-Control: max-age=0.
Responses that depend on cookies, authentication, or other user‑specific data.
HTTPS resources unless the server explicitly marks them cacheable (e.g., Cache-Control: public).
POST requests.
Responses lacking any of Cache-Control, Expires, Last-Modified, or Etag.
Practical Configuration Tips
Keep resource URLs stable; shared libraries benefit from cross‑site caching.
Assign long max-age values to static assets (CSS, JS, images) and avoid caching the entry HTML page.
Minimize cookie transmission for static resources to reduce request size and improve cacheability.
Serve static assets over HTTP when security is not required; use HTTPS only for sensitive data.
Prefer GET over POST for idempotent requests, as GET responses can be cached.
For dynamic scripts that produce identical output within a time window, expose them as static files with Last-Modified or Etag headers.
Configure server‑side frameworks to emit Cache-Control: max-age=… and optionally Last-Modified or Etag for dynamic responses.
Summary Flow
1. Browser checks its cache for a matching URL.
2. If a fresh entry exists (per Cache-Control / Expires), the response is served directly (strong cache).
3. If the entry is stale, the browser sends a conditional request with validators.
4. Server replies 304 to reuse the cached copy or 200 with a fresh body.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
