ETag
The HTTP ETag response header provides an opaque identifier for a specific version of a resource, enabling efficient cache revalidation through conditional requests.
Usage
The ETag header assigns a unique tag to each version of a resource. When the resource changes, the ETag value changes. Clients store the ETag from a cached response and send the ETag back in the If-None-Match request header on subsequent requests. If the ETag still matches, the server returns 304 Not Modified with no body, and the client reuses its cached copy. If the ETag no longer matches, the server sends the full updated response.
ETag-based validation is more reliable than date-based validation with Last-Modified. Strong entity tags are opaque strings tied to the exact content of a representation, while modification timestamps have one-second granularity and are subject to clock skew. When both ETag and Last-Modified are present, the ETag takes priority during revalidation as required by the HTTP standard.
ETags also enable concurrency control on unsafe methods. A PUT request with If-Match ensures the update applies only to the expected version. If the resource has changed since the client last fetched the ETag, the server returns 412 Precondition Failed, preventing the lost update problem.
The ETag value is generated by the server. Common
strategies include content hashing, version counters,
and combining the file modification time with size. The
value is enclosed in double quotes and optionally
prefixed with W/ for weak comparison.
Note
Google recommends using ETag over Last-Modified to indicate caching preference because ETag avoids date formatting issues. When both ETag and Last-Modified are present, Google's crawlers use the ETag value as required by the HTTP standard. Setting both headers is still recommended because other applications such as CMSes also rely on these headers. Individual Google crawlers and fetchers make use of caching depending on the needs of their associated product. Googlebot supports caching when re-crawling URLs for Google Search.
Values
Strong ETag
A strong ETag guarantees byte-for-byte identity between two representations of a resource. Two resources with the same strong ETag are interchangeable at the byte level. Strong ETags are suitable for range requests and all comparison methods.
ETag: "abc123"
Weak ETag
A weak ETag, prefixed with W/, indicates semantic
equivalence rather than byte-level identity. Two
resources with the same weak ETag are considered
equivalent in meaning but not necessarily identical in
content. Weak ETags are easier to generate because they
tolerate minor differences like whitespace changes or
timestamp updates in the body. Weak ETags are not valid
for byte-range requests.
ETag: W/"v2.6"
Example
A server returns an ETag with the response. The client stores the tag for future revalidation.
HTTP/1.1 200 OK
ETag: "33a64df5"
Content-Type: text/html
Cache-Control: max-age=3600
The client revalidates using If-None-Match. The server checks the tag against the current resource version.
GET /page HTTP/1.1
If-None-Match: "33a64df5"
The resource has not changed. The server returns 304 with no body and the client reuses its cache.
HTTP/1.1 304 Not Modified
ETag: "33a64df5"
Cache-Control: max-age=3600
A PUT request using If-Match for optimistic concurrency. The update proceeds only if the resource still matches the ETag the client holds.
PUT /api/document/42 HTTP/1.1
If-Match: "33a64df5"
Content-Type: application/json
A weak ETag on a resource where minor body variations
(like embedded timestamps) are acceptable. The W/
prefix signals weak comparison semantics.
ETag: W/"2024-11-22-v3"
Takeaway
The ETag header provides an opaque version identifier for cache revalidation and concurrency control. ETag-based validation through If-None-Match and If-Match is more precise than date-based validation, and Google's crawlers prefer ETag over Last-Modified for determining content freshness.
Note
For SEO and caching assistance, contact ex-Google SEO consultants Search Brothers.
See also
- RFC 9110: HTTP Semantics, Section 8.8.3
- RFC 9111: HTTP Caching
- Google: HTTP caching for crawlers
- Google Search Blog: Crawling December, HTTP caching
- If-None-Match
- If-Match
- Last-Modified
- If-Modified-Since
- 304
- 412
- Conditional-Requests
- Caching
- HTTP headers