Skip to content
Glossary

What Is ETags?

ETags (entity tags) are HTTP response headers that give a specific version of a file a unique identifier, such as a hash of its contents. When the file changes, its ETag changes, so browsers and CDNs can ask the server whether their cached copy is still current and receive a small 304 Not Modified response instead of downloading the whole file again.

What Are ETags?

An ETag is a validator defined in the HTTP specification (RFC 9110, HTTP Semantics). The server sends it as a response header such as ETag: "33a64df5", where the quoted value means nothing to the browser: it only has to change whenever the content changes. Servers generate ETags in different ways. Some hash the response body, while Nginx, for example, builds the value from the file's last-modified time and size. There are two kinds. A strong ETag promises that the bytes are identical, while a weak ETag, written with a W/ prefix as in W/"33a64df5", only promises that two versions are equivalent in meaning, which lets a server keep the same validator when it compresses a file on the fly. ETags do the same job as the older Last-Modified header but are more precise: Last-Modified has one-second resolution and changes whenever a file is rewritten, even with identical content, whereas a content-based ETag only changes when the bytes do.

How ETags Work

On the first request the server returns the file with a 200 OK status, an ETag header and usually a Cache-Control header that says how long the copy stays fresh. The browser stores all three. Once the cached copy is stale (its max-age has passed) or the server sent Cache-Control: no-cache, the browser does not simply download the file again. It sends a conditional request that includes If-None-Match: "33a64df5". The server compares that value with the current ETag. If they match, it replies 304 Not Modified with headers only and no body, and the browser reuses its stored copy and resets its freshness. If they differ, the server sends a normal 200 response with the new content and a new ETag. CDNs follow the same cycle when they revalidate cached objects with your origin server, which keeps edge caches accurate without refetching every file. ETags also support safe updates in APIs: a client can send If-Match with the ETag it last saw, and the server returns 412 Precondition Failed if someone else changed the resource in the meantime, which stops one edit from silently overwriting another. You can watch the whole exchange in the Network panel of Chrome DevTools, where revalidated files show a 304 status and a transfer size of only a few hundred bytes.

Best Practices for ETags

Treat ETags as one part of a caching strategy rather than a substitute for it. For fingerprinted static assets whose file name changes on every build, such as app.3f9a1c.css, send Cache-Control: public, max-age=31536000, immutable so browsers skip revalidation entirely; the ETag then rarely matters. For HTML documents and other files that keep the same URL while their content changes, pair an ETag with Cache-Control: no-cache or a short max-age, so repeat visitors get fast 304 responses and still see updates immediately. If you run several servers behind a load balancer, make sure every server generates the same ETag for the same file. Older Apache configurations included the file's inode number, which differs between machines and caused needless full downloads; FileETag MTime Size avoids that. Be aware that deployment tools which rewrite every file also change modification times, and with them any ETags based on timestamps. Check your headers after each deploy with curl -I https://example.com/ and repeat the request with -H 'If-None-Match: "value"' to confirm the server answers 304. Finally, do not repurpose ETags to identify returning users: they were designed for cache validation, and using them as tracking identifiers raises the same privacy and consent issues as cookies.

ETags and Canvas Builder

ETags are set by the web server or CDN that hosts your files, not by the HTML, so pages built with Canvas Builder neither add nor block them. When you export a site as a ZIP and upload it to Nginx, Apache or a static host, the server normally generates ETags for the HTML, CSS, JavaScript and image files automatically. After deploying, check the response headers once to confirm that repeat visits return 304 responses or come straight from the browser cache.

Start building free

Frequently asked questions

What is the difference between an ETag and Last-Modified?

Both are validators that let a browser check whether its cached copy is still current. Last-Modified is a date with one-second precision that the browser sends back in If-Modified-Since, while an ETag is an opaque identifier sent back in If-None-Match. When a request carries both, the HTTP specification tells servers to evaluate If-None-Match and ignore If-Modified-Since.

What does a 304 Not Modified response mean?

A 304 status means the server checked the validator the browser sent, such as an ETag, and found the resource unchanged. The response contains headers but no body, so the browser loads the file from its own cache. It still costs a round trip to the server, which is why long-lived, fingerprinted assets are better served with immutable caching that avoids the request altogether.

Should I disable ETags?

Usually not. Older performance guides recommended turning them off because some multi-server setups generated different ETags for the same file, which defeated caching. If your ETags are consistent across servers, they save bandwidth on every revalidation; if they are not, fix the configuration or rely on Last-Modified instead.

What is a weak ETag?

A weak ETag starts with W/, for example W/"5e15153d", and signals that two versions are equivalent in meaning even if their bytes differ slightly. Servers often switch to weak ETags when they compress responses on the fly. Weak ETags work for normal cache revalidation with If-None-Match but cannot be used for byte-range requests.