Skip to content
Conditional Requests & ETags
step 1/5

Reading — step 1 of 5

Read

~1 min readCaching, Compression & Beyond

Conditional Requests & ETags

Browsers and CDNs revalidate cached responses before refetching them. The two mechanisms are time-based (Last-Modified / If-Modified-Since) and hash-based (ETag / If-None-Match). Both turn a 200 OK with body into a tiny 304 Not Modified with no body — saving bandwidth, latency, and money.

ETag flow

# First request — server returns body + ETag
GET /static/app.css HTTP/1.1
  -> HTTP/1.1 200 OK
     ETag: "a1b2c3"
     Content-Length: 4823
     ...body...

# Revalidation — client echoes the ETag
GET /static/app.css HTTP/1.1
If-None-Match: "a1b2c3"
  -> HTTP/1.1 304 Not Modified
     ETag: "a1b2c3"
     (no body)

Rules

  • Strong ETag ("abc") — byte-exact match required
  • Weak ETag (W/"abc") — semantic match (e.g. minified vs not)
  • A 304 response MUST include the same ETag and any cache-control headers, MUST NOT include a body, and SHOULD NOT include Content-Length.
  • If If-None-Match: * is sent, match on existence (used by PUT for optimistic concurrency, returning 412 Precondition Failed if present).

Last-Modified flow

  -> HTTP/1.1 200 OK
     Last-Modified: Tue, 15 Nov 2025 12:00:00 GMT

GET ...
If-Modified-Since: Tue, 15 Nov 2025 12:00:00 GMT
  -> HTTP/1.1 304 Not Modified

Most servers send both. ETag wins when both are present (it's exact). Hash production for ETag: usually SHA-1 / xxHash of the file's bytes, hex-encoded.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…