ETag

An ETag (entity tag) is an HTTP response header that identifies a specific version of a resource — typically a hash of its content. It lets browsers and CDNs ask "has this changed?" instead of re-downloading the whole thing: the client sends the ETag back in an If-None-Match request header, and if the version still matches, the server answers 304 Not Modified with an empty body.

How ETag revalidation works

The first response carries the tag:

HTTP/2 200
etag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
cache-control: max-age=3600

Once the cached copy's TTL expires, the client revalidates instead of refetching:

GET /style.css
if-none-match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

HTTP/2 304 Not Modified

A 304 costs one round trip but no body transfer — for a large asset that's the difference between milliseconds and a full re-download. CDNs use the same mechanism upstream: an edge server revalidates its stale copy against your origin and refreshes the entry's freshness without moving bytes.

Strong vs. weak ETags

A strong ETag ("abc123") promises byte-for-byte identity. A weak ETag (W/"abc123") promises only semantic equivalence — the content is "the same enough" (say, a timestamp in a footer changed). Weak ETags can't be used for byte-range requests, but both work for revalidation.

The pitfalls worth knowing

ETags and CDN caching

Revalidation makes expiry cheap, but the visitor still waits for the origin round trip whenever the edge copy has expired. That's why a healthy setup combines sensible ETags with a long s-maxage — and re-warms edge caches after purges, so real visitors hit fresh copies instead of triggering revalidations. See our cache hit ratio guide for where revalidation fits into the bigger picture.