Skip to content

Glossary

ETag

HTTP entity tag for cache validation

By Published Updated

An ETag (Entity Tag) is an HTTP response header — typically a hash or version stamp of the response body — that lets a client revalidate a cached resource without downloading it again.

Workflow:

  1. First request: server returns the resource with ETag: "abc123".
  2. Client caches the response with the ETag.
  3. Next request: client sends If-None-Match: "abc123".
  4. Server compares the current ETag to the client’s. If equal: 304 Not Modified with an empty body, client uses its cached copy. If different: 200 OK with the new body and new ETag.

Two ETag flavours:

  • Strong ETags — change if the bytes change. Default.
  • Weak ETags — prefixed W/, may match across “semantically equivalent” responses (e.g., compressed vs uncompressed of the same content).

ETag is one of three HTTP cache-validation mechanisms (alongside Last-Modified + If-Modified-Since, and Cache-Control max-age). For modern static sites with content-hashed asset URLs, ETag is rarely necessary — but it remains the workhorse for dynamic APIs that want client-side caching.

Worked example

A browser fetches /api/profile for the first time. The server responds: HTTP/1.1 200 OK, ETag: "v42-7a8b9c", body = 4.2 KB of JSON. The browser caches both. Next page load, the browser sends GET /api/profile with If-None-Match: "v42-7a8b9c". The server computes the current ETag — still "v42-7a8b9c" because nothing changed — and responds HTTP/1.1 304 Not Modified with zero bytes of body. The browser serves its cached copy. Bandwidth saved: 4.2 KB; round-trip latency still paid. Compare with Cache-Control: max-age=300, which skips the round-trip entirely for 5 minutes — and you see why ETag is the second-best caching strategy: it confirms freshness when staleness must be avoided, but it doesn’t actually save the network round-trip. Modern static sites prefer fingerprinted URLs + far-future max-age and skip ETag entirely.

When and why it matters

ETag matters for two distinct workflows: cache revalidation (saving bandwidth when responses are large and unchanging) and optimistic concurrency control (preventing lost-update bugs in REST APIs). The mistake to avoid in caching is generating a weak ETag from a timestamp that includes sub-second precision — every server in a load-balanced cluster computes a different value for the same resource, and clients constantly invalidate. Use a stable content hash (SHA-256 of the body, often truncated to 16 chars) so all replicas produce the same ETag. The mistake to avoid in concurrency is failing to validate If-Match server-side — many developers add the header on writes but the server ignores it, leaving the race condition unfixed. AWS S3, Google Cloud Storage, and Stripe’s API all enforce ETag-based concurrency strictly; following their pattern is the safest reference design. Reference: MDN — ETag HTTP header.

Optimistic concurrency control — ETag’s second job: ETag is also the standard mechanism for “don’t overwrite my data if someone else changed it”. The client GETs the resource, captures the ETag, makes edits, then PUTs back with If-Match: "abc123". If the server-side resource has changed since (different ETag), the server returns 412 Precondition Failed and the client knows to refresh and re-merge. AWS S3, Google Cloud Storage, and most REST APIs that support concurrent edits use this exact pattern. The mechanism predates web-app pessimistic locking and is more scalable because no server-side lock state is needed.

The privacy concern with ETags: servers can use unique per-user ETag values (essentially a server-issued cookie embedded in cache metadata) to track returning users without setting an actual cookie — the so-called “ETag cookie” or “supercookie”. Even after a user clears cookies, the browser still sends the ETag back on the next request, identifying them. Browsers now partition HTTP caches per top-level site (Chrome 86, Firefox 85) to neutralise this attack, but the technique remains a known privacy footnote in HTTP caching design. Reference: RFC 9110 §8.8.3 — ETag.

Frequently asked questions

What is an ETag?
An ETag (entity tag) is an HTTP response header containing an opaque identifier — typically a hash or version number — for a specific version of a resource. When the resource changes, the ETag changes. Browsers use ETags to validate cached copies without re-downloading the full content.
How does ETag caching work in practice?
A server sends ETag: "abc123" with a response. On the next request, the browser sends If-None-Match: "abc123". If the resource is unchanged, the server returns 304 Not Modified with no body — saving bandwidth. If changed, it returns 200 with new content and a new ETag.
What is the difference between ETag and Last-Modified?
Last-Modified is a timestamp-based validator; ETag is a content-based hash. ETags are more reliable for sub-second changes (timestamps have 1-second resolution) and for dynamic resources where content may change back to a previous state (same ETag = no re-download). ETags are preferred when precision matters.
What is a strong vs weak ETag?
A strong ETag (ETag: "abc123") guarantees byte-for-byte identity between the cached and current resource. A weak ETag (ETag: W/"abc123") indicates semantic equivalence — the content is the same for the user's purposes but may differ in compression or minor formatting. Weak ETags cannot be used with range requests.

Related

Published May 15, 2026 · Last reviewed May 31, 2026