E-Tag
ETag (short for Entity Tag) is a mechanism used in HTTP headers to manage web cache validation and optimistic concurrency control. It is part of the HTTP specification (defined in RFC 7232) and is commonly used in REST APIs to:
- Avoid unnecessary data transfers (by caching and validating resources).
- Prevent lost updates (by safely updating only the latest version of a resource).
How E-Tag Works
When a client retrieves a resource via a GET request, the server responds with an ETag header. This ETag is a hash or version identifier representing the current state of the resource.
The client can then:
-
Send that ETag back to the server on subsequent requests using conditional headers:
If-None-Match(forGET)If-Match(forPUT,DELETE, etc.)
The server compares the sent ETag with the current version and acts accordingly.
Caching with If-None-Match
Client Request (initial GET)
GET /products/123 HTTP/1.1
Host: api.example.com
Server Response
HTTP/1.1 200 OK
ETag: "abc123"
Content-Type: application/json
{
"id": 123,
"name": "Wireless Mouse",
"price": 29.99
}
Client Request (subsequent GET with ETag)
GET /products/123 HTTP/1.1
Host: api.example.com
If-None-Match: "abc123"
Server Response (not modified)
HTTP/1.1 304 Not Modified
Benefit: Saves bandwidth and reduces server load if the resource hasn’t changed.
Optimistic Concurrency Control with If-Match
Client Wants to Update a Product:
-
It first
GETs the product and receives:ETag: "abc123" -
It modifies the data locally and sends a
PUT:PUT /products/123 HTTP/1.1
Host: api.example.com
If-Match: "abc123"
Content-Type: application/json
{
"name": "Wireless Mouse",
"price": 24.99
} -
Server checks the current ETag. If it still matches
abc123, the update is accepted. If another client has already modified it, the ETag would be different.
If Outdated
HTTP/1.1 412 Precondition Failed
Generating ETags
Weak ETags: prefixed with W/, allow for semantically equivalent content changes.
ETag: W/"xyz456"
Strong ETags: strict bit-by-bit comparison.
ETag: "abc123"
ETags can be:
- A hash of the resource (e.g. MD5 or SHA).
- A version number, timestamp, or database record version field (e.g.,
updated_at,row_version).