Freshness and caching
Last-Modified and ETag: what page headers say about freshness
Last-Modified and ETag tell a cache whether a copy changed, not when the content was written. How reliable each one is, and what to store instead.
Published
This article was drafted with AI assistance from the sources listed below and edited and published by Teneo Labs. Disclosure: this site is run by Teneo Labs, the company behind Live Web Data API, which this article mentions.
| Criterion | Last-Modified | ETag |
|---|---|---|
| What it is | A date, to the second | An opaque version tag |
| Answers | Changed since this date? | Still the same version? |
| Conditional header | If-Modified-Since | If-None-Match |
| Says when content was written | No, only when the server says it changed | No |
HTTP gives every response two optional freshness hints: the Last-Modified date and the ETag version tag. It is tempting to read them as "this page was updated on…" and pass that to the model. Both headers were designed for a narrower job, and knowing that job tells you how far to trust them.
What the headers are for
RFC 9110 calls both headers validators. Their job is to let a cache ask the origin server a cheap question: "I have a copy; has it changed?" The cache sends If-Modified-Since with the stored date or If-None-Match with the stored ETag. If nothing changed, the server answers 304 Not Modified without a body, and the cache keeps using its copy.
That is a statement about the response, as the server sees it. It is not a statement about when the article, price or policy on the page was written.
Where Last-Modified goes wrong
MDN describes Last-Modified as the date the origin server believes the resource was last modified, with one-second resolution. "Believes" is doing a lot of work:
- Generated pages often send the time of the request, so every fetch looks brand new.
- Static site builds can stamp every file with the build time, so a page untouched for a year looks as fresh as yesterday's post.
- Some servers omit it, and some CDNs rewrite it.
For an LLM app, the result is the same in every case: the header cannot tell the model whether the facts on the page are current.
Where ETag goes wrong
An ETag is an opaque identifier for one version of a resource. MDN and RFC 9110 both distinguish strong tags from weak ones (prefixed W/), which only promise that two responses are equivalent for caching. The value has no defined format, so you cannot read a date or a version number out of it. It changes when anything in the response changes, including parts the model does not care about, such as a rotating banner.
What to record instead
Treat validators as hints for caching, and record the facts you can vouch for:
- Fetch time, taken by your own code when the response arrives.
- Source status: whether the copy was read live or came from a cache (yours or a provider's), and how old it was allowed to be.
- Published date from the page, when the page exposes one, labelled as the page's own claim.
- Final URL and country, so the age belongs to a specific version of the page.
Then tell the model the fetch time in the prompt, as the live vs cached web data guide shows.
How this maps to Live Web Data API
The API does not pass the target site's response headers through. It returns the content, a publishedDate when the page exposes one, and per URL a statuses[].fetchedAt with the time the page was read. There is no cache, so every result was read live during your request. Store fetchedAt next to the content. The API reference lists every response field.
Frequently asked questions
Can I use Last-Modified as the published date of an article?
No. It is the server's idea of when the response last changed. A template edit, a new comment count or a rebuild of the whole site can move it. Use a published date from the page itself, when the page exposes one.
What does a weak ETag mean?
An ETag that starts with W/ says two responses are equivalent enough for caching, not byte-for-byte identical. It is a signal for caches, not a content checksum you can compare across fetches.
Sources
- Last-Modified (MDN) (Documentation)
- ETag (MDN) (Documentation)
- RFC 9110: HTTP Semantics (Documentation)