ETag / conditional requests
A header giving a resource a version fingerprint; clients send it back to check if it changed (304 Not Modified) or to avoid concurrent overwrites (If-Match). Saves bandwidth and enables optimistic concurrency. Built into HTTP.
- Caching and revalidation (304s).
- Optimistic concurrency on writes (If-Match).
- Resources that change every request (no caching benefit).
- When you need server-side locking instead.
Definition
An ETag is a hash/version of a representation. GET with If-None-Match returns 304 if unchanged (no body). PUT with If-Match only succeeds if the ETag matches, preventing lost updates. Weak ETags are semantically equal, strong byte-equal.
Why it exists
Re-downloading unchanged resources wastes bandwidth; overwriting based on stale reads loses updates. ETags make caching and optimistic concurrency cheap and standard.
How it works
Server computes an ETag (hash of content/version). Client caches it. On revalidate, sends If-None-Match; server returns 304 if it matches. On write, sends If-Match: "etag"; server rejects (412) if someone else changed it. CDNs use ETags for revalidation.
Scaling limits
ETag computation adds CPU. Strong ETags break under content-encoding differences. Conditional writes need the client to have fetched the current ETag first.
Cost shape
Negligible. Saves bandwidth and prevents lost updates. Blow-ups: expensive ETag computation per request.
Alternatives
- Last-Modified — Coarser time-based revalidation.
- Version field in payload — Same idea, app-level, not HTTP-standard.
Failure modes
- Weak vs strong ETag confusion.
- ETag not varying with content (stale 304s).
- Hash collisions in weak schemes.