ETag vs Last-Modified: Which Validator Should You Use?
httpetaglast-modifiedheaderscdncaching

ETag vs Last-Modified: Which Validator Should You Use?

ccached.space Editorial
2026-06-08
11 min read

A practical guide to choosing ETag, Last-Modified, or both for reliable HTTP cache validation across apps, APIs, and CDNs.

Choosing between ETag and Last-Modified is less about picking a winner and more about matching an HTTP validator to how your content is created, deployed, and cached. This guide compares both validators in practical terms: how they work, where each one is strong, where they can create friction, and how to decide on a cache validation strategy that still makes sense as your app, CDN setup, and release workflow evolve.

Overview

If you want conditional requests to work well, you need validators that are predictable across your whole delivery path: browser, CDN, reverse proxy, app server, and storage layer. That is where the ETag vs Last-Modified decision matters.

Both headers help clients revalidate cached responses instead of downloading the full payload again. When a browser or intermediary cache has a stored response, it can ask the origin whether that representation has changed. If not, the server can return 304 Not Modified, saving bandwidth and often reducing response time. If you want a deeper look at the tradeoffs of revalidation itself, see 304 Not Modified Explained: When Revalidation Helps or Hurts.

The two validators answer the same high-level question in different ways:

  • Last-Modified says, in effect, “this resource was last changed at this time.”
  • ETag says, “this exact representation has this identifier.”

That difference sounds small, but it affects correctness, cache hit patterns, deployment safety, and debugging.

Last-Modified is time-based. It is simple, readable, and often good enough for many static assets and content responses. It works best when the resource has a meaningful modification timestamp and your system can expose it consistently.

ETag is identity-based. It can be much more precise because it is tied to a specific representation, not just a timestamp. That precision makes it attractive for APIs, personalized payloads, generated documents, and resources where sub-second changes or exact byte-level matching matter.

In practice, many teams do not fail because they picked the wrong validator in theory. They fail because the validator does not survive the reality of distributed systems. Common examples include:

  • ETags generated differently on different nodes behind a load balancer
  • Last-Modified values that reflect deploy time rather than content change time
  • Compressed and uncompressed variants sharing the wrong validator
  • Static asset pipelines that already use versioned filenames, making revalidation less important than long freshness
  • CDN rules that strip, rewrite, or ignore validators in unexpected ways

The practical question is not “Which header is better?” It is “Which validator gives me accurate revalidation with the lowest operational cost in this part of my stack?”

How to compare options

To choose well, compare ETag and Last-Modified against your actual resource types, not against abstract HTTP examples. The right answer for a JSON API is often different from the right answer for built assets, generated reports, or CMS pages.

Use these criteria.

1. Precision of change detection

If your resource can change multiple times within a short interval, time-based validation may be too coarse. Last-Modified usually works at the level of a timestamp, and depending on your platform, timestamp resolution may not reflect every meaningful change. ETag can represent the exact version of the payload, which makes it a better fit when precision matters.

Ask: do you need to know whether the representation is exactly the same, or just whether it is probably unchanged since a known update time?

2. Ease of generation

Last-Modified is often easier to expose because many systems already track an updated-at field, file mtime, or publication time. ETag may require you to hash content, calculate a revision identifier, or surface a storage-layer version token.

Ask: can your application generate a stable validator cheaply on every response?

3. Consistency across servers and deploys

This is where many implementations break. If your ETag depends on local file metadata, inode values, or server-specific generation logic, identical resources may produce different ETags on different machines. That leads to unnecessary misses and confusing revalidation behavior.

Last-Modified can also drift if timestamps are assigned by different components or reset during deployments.

Ask: will the validator stay the same for the same representation no matter which node serves it?

4. Interaction with transformations

CDNs, proxies, and app servers often transform responses through compression, minification, image conversion, or edge-side assembly. If the validator is tied to the uncompressed origin response but the client receives a transformed variant, you need to be careful. ETag can be powerful here, but only if it is scoped to the served representation or paired with correct Vary behavior.

Ask: does anything between origin and user change the bytes of the response?

5. Operational simplicity

Simple systems age better. A less precise validator that is correct and easy to reason about is usually better than a sophisticated one that occasionally lies. Last-Modified is easier for humans to inspect. ETags are more flexible, but more opaque.

Ask: can your team debug this quickly during an incident?

6. Resource volatility and cache policy

Validators matter most when revalidation is part of the strategy. If your static assets use content-hashed filenames and long Cache-Control lifetimes, validators may matter less because the URL changes when the asset changes. On the other hand, for HTML, API responses, feeds, and dashboards, validators are often central to efficient freshness checks.

Ask: are you optimizing for long-lived immutable caching, or frequent revalidation of stable URLs?

For a broader implementation checklist, HTTP Caching Checklist for Production Sites is a useful companion.

Feature-by-feature breakdown

This section compares ETag caching and Last-Modified header behavior side by side, with the tradeoffs that usually matter in production.

Accuracy

ETag: Usually more accurate. It can identify a specific representation and works well when even small response changes matter.

Last-Modified: Good enough when content changes are infrequent or when timestamp-based freshness aligns with the business meaning of “updated.” It may miss edge cases where content changes without a meaningful timestamp difference.

Practical takeaway: If exact matching matters, prefer ETag. If “changed recently enough” is acceptable, Last-Modified may be sufficient.

Implementation effort

ETag: Medium to high effort, depending on how it is generated. Hashing a large body on every request can be expensive; deriving the ETag from a version field, revision ID, or object checksum is usually cleaner.

Last-Modified: Low effort when you already have a reliable modification timestamp.

Practical takeaway: If your stack already has a trustworthy updated-at signal, Last-Modified is often the fastest correct option.

Human readability and debugging

ETag: Harder to inspect. You can compare values, but they usually do not explain themselves.

Last-Modified: Easy to read in logs, DevTools, and cURL output. It helps when teams are troubleshooting cache behavior under time pressure.

Practical takeaway: Last-Modified is easier for manual diagnosis, especially for teams that do not specialize in caching.

Suitability for distributed systems

ETag: Excellent if generated from shared canonical data; risky if generated from node-local details.

Last-Modified: Also solid if the timestamp comes from a canonical source such as a database record or object storage metadata.

Practical takeaway: Both work in distributed systems when backed by shared state. Both fail when derived from inconsistent local state.

Sensitivity to deployment patterns

ETag: Can break during blue-green deploys, rolling updates, or multi-region delivery if different app versions generate different identifiers for identical output.

Last-Modified: Can produce false positives when deploys touch file timestamps without actual content changes.

Practical takeaway: Tie the validator to content or canonical metadata, not incidental deployment artifacts.

Compatibility with generated and dynamic content

ETag: Often the better choice for APIs and rendered responses assembled from multiple sources, provided the tag maps to a meaningful content version.

Last-Modified: Works when you can define a single meaningful update time, such as “latest record change among all included entities.” That can be harder than it sounds.

Practical takeaway: Dynamic composite content tends to favor ETag unless you have a clean aggregate timestamp.

Bandwidth savings vs compute cost

ETag: Saves bandwidth through exact revalidation, but computing the tag can add server cost if done naively.

Last-Modified: Lightweight to generate, but sometimes less precise in avoiding unnecessary transfers.

Practical takeaway: Do not spend more CPU generating validators than you save in transfer and origin work. Use cheap version sources where possible.

Strong vs weak validation

One useful distinction inside ETag strategy is strong versus weak ETags. A strong ETag implies byte-for-byte identity of the representation. A weak ETag, usually prefixed in a way that marks it as weak, signals semantic equivalence rather than exact bytes.

That matters when responses are transformed or serialized in slightly different but equivalent ways. Weak ETags can reduce churn in some systems, but they require care and a clear understanding of what “same enough” means for your clients.

Practical takeaway: If you need exact representation matching, use strong ETags. If semantic sameness is enough and transformations are common, weak ETags may be reasonable.

Should you use both?

Often, yes. Sending both ETag and Last-Modified gives clients and intermediaries more information, and it can improve compatibility across different implementations. But only do this if both values are accurate and derived consistently. Two validators that disagree are worse than one validator you trust.

A good rule is simple: emit both when both are cheap and correct; otherwise choose the one you can maintain confidently.

Best fit by scenario

The easiest way to settle the ETag vs Last-Modified question is by resource type and deployment pattern.

Scenario 1: Versioned static assets

If your CSS, JS, fonts, and images ship with content-hashed filenames, long-lived freshness usually matters more than revalidation. In that setup, validators are less central because a changed file gets a new URL.

Best fit: Either validator can work, but it is usually not the main optimization lever. Focus first on immutable caching and naming discipline.

Scenario 2: Static files without filename versioning

If asset URLs remain stable across releases, validators matter more. Last-Modified is often enough for simple sites. ETag can be more precise if deploy tooling preserves content identity better than timestamps.

Best fit: Start with Last-Modified if file modification times are reliable. Use ETag if timestamps are noisy or precision matters.

Scenario 3: JSON APIs backed by database records

For APIs, clients often poll stable URLs for updates. If you can derive a validator from a row version, revision number, or aggregate checksum, ETag is typically the stronger choice. If the response reflects a single resource with a trustworthy updated-at field, Last-Modified can also work well.

Best fit: Prefer ETag for exact API representation tracking; use Last-Modified when a canonical update timestamp is already available and meaningful.

Scenario 4: Aggregated or composite responses

Consider an endpoint that joins several tables, feature flags, and personalization inputs. A single Last-Modified value may be hard to compute correctly. An ETag based on a response version key or dependency fingerprint is often more realistic.

Best fit: ETag.

Scenario 5: CDN in front of multiple origins

In multi-origin or multi-region setups, consistency matters more than theoretical accuracy. If an ETag differs by region for identical content, revalidation becomes noisy. If Last-Modified comes from synchronized canonical metadata, it may actually be safer.

Best fit: Choose the validator you can keep stable globally. That may be ETag or Last-Modified depending on your architecture.

Scenario 6: CMS pages and editorial content

Content pages usually have a clear publish or update time, and minor timestamp imprecision is rarely a problem. Editors and support teams also benefit from readable headers during troubleshooting.

Best fit: Last-Modified, optionally with ETag if your platform provides a stable content revision ID.

Scenario 7: Personalized responses

If the response varies by authentication, locale, experiment bucket, or user profile, validator strategy becomes more delicate. You need correct cache partitioning first, usually through Cache-Control and Vary. After that, ETag can still be useful, but only if it maps to the personalized representation the client actually receives.

Best fit: Usually ETag, but only after you have variant handling under control.

Scenario 8: Object storage and file delivery

If your files live in storage systems that already expose stable metadata such as object version IDs, checksums, or modification times, your best choice is often the one that aligns with that metadata. Avoid recomputing what the storage layer already knows.

Best fit: Follow canonical storage metadata. ETag if the object identifier is stable and meaningful; Last-Modified if modification metadata is authoritative.

A simple decision rule

  • Use Last-Modified when you have a trustworthy, canonical modification time and do not need exact byte-level precision.
  • Use ETag when you need exact representation validation or when timestamps are hard to define correctly.
  • Use both when both are easy to generate, stable across your stack, and not contradictory.

When to revisit

Your validator strategy should not be a one-time configuration. Revisit it when the system around it changes, because validators that worked in a simple app can become misleading after architecture changes.

Review your choice when any of these happen:

  • You add a CDN or change CDN behavior. Edge compression, normalization, and cache key changes can affect validator correctness.
  • You move from one server to multiple nodes or regions. Distributed delivery exposes unstable generation logic quickly.
  • You change deployment style. Rolling deploys, container rebuilds, and artifact repackaging may alter timestamps or ETag generation inputs.
  • You switch to content-hashed asset URLs. Validators may become secondary for some resources and still essential for others.
  • You introduce API aggregation or personalization. A single update time may no longer describe the representation accurately.
  • You see unexplained 200s where you expected 304s. This usually signals a validator mismatch, a cache-key problem, or a transformation issue.
  • You see too many 304s for resources that should be fresh longer. In that case, the problem may be your freshness policy rather than the validator itself.

Here is a practical audit process you can reuse:

  1. Pick three representative resource types: a static asset, an HTML page, and an API response.
  2. Inspect current response headers with browser DevTools and cURL.
  3. Confirm whether the validator source is canonical or incidental.
  4. Test revalidation through the CDN, not just directly against origin.
  5. Repeat the request across deploys and, if possible, across regions or nodes.
  6. Check whether compressed and uncompressed variants behave consistently.
  7. Decide whether the observed behavior matches your intended cache validation strategy.

If you want an action-oriented next step, document validator policy per resource class. A short internal table is enough:

  • Static hashed assets: long freshness, validator optional
  • HTML pages: short freshness plus Last-Modified or ETag
  • API resources: ETag from version field or canonical timestamp if simple
  • Aggregated endpoints: ETag from dependency fingerprint

That kind of explicit policy prevents one default server setting from silently controlling every response type.

The main point is straightforward: choose validators based on how your content changes and how your infrastructure serves it. Last-Modified is often the simplest correct answer. ETag is often the most precise. The better choice is the one your system can generate consistently, your team can debug confidently, and your cache layers can honor without surprises.

Related Topics

#http#etag#last-modified#headers#cdn#caching
c

cached.space Editorial

Senior SEO Editor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

2026-06-09T23:29:54.666Z