Short answer: HTTP caching headers tell browsers and crawlers whether a page has changed since they last fetched it. When your server sends an ETag or Last-Modified header and answers repeat requests with 304 Not Modified when nothing changed, crawlers can skip downloading unchanged pages and spend their time on new or updated ones. It is not a ranking factor, but on larger sites it makes crawling more efficient, and wrong caching headers can hide real updates from search engines.
What HTTP caching headers are
Every time a browser or crawler requests a page, your server answers with a status code, a set of headers and the page itself. Some of those headers are about caching: they describe how long a copy may be reused and how a client can check whether its copy is still current. The rules are defined in the HTTP caching standard, RFC 9111, and explained in friendlier language in MDN’s guide to HTTP caching.
There are two families of caching headers, and it helps to keep them apart:
- Freshness headers such as
Cache-Control: max-age=...andExpiressay how long a stored copy can be used without asking the server again. - Validators such as
ETagandLast-Modifiedgive the stored copy an identity, so the client can later ask “has this changed?” instead of downloading everything again.
For SEO, validators matter most. Crawlers usually do not reuse a copy blindly for hours; they come back and ask whether the page changed. Validators let your server answer that question cheaply.
How conditional requests and 304 responses work
A conditional request is a normal request with one extra header that refers to the copy the client already has. The flow looks like this:
- The crawler fetches
/services/for the first time. Your server returns200 OK, the HTML, and headers such asETag: "a1b2c3"andLast-Modified: Tue, 08 Sep 2026 10:00:00 GMT. - Days later, the crawler requests the same URL again and adds
If-None-Match: "a1b2c3"and/orIf-Modified-Since: Tue, 08 Sep 2026 10:00:00 GMT. - If the page is unchanged, the server replies
304 Not Modifiedwith no body. The crawler keeps its stored copy. - If the page changed, the server replies
200 OKwith the new HTML and a newETagandLast-Modified.
A 304 response is tiny compared to a full HTML page, so the saving is real for both sides: less bandwidth and server work for you, and faster checks for the crawler. For a status code overview, see our guide to the HTTP status codes that matter for SEO.
Why caching headers matter for crawling
Google has documented that its crawlers support conditional requests with ETag/If-None-Match and Last-Modified/If-Modified-Since, and it has said that ETag is the less error-prone option when you can choose. Bing and other crawlers also understand these headers because they are a standard part of HTTP.
What you gain depends on the size of the site:
- Small sites with a few hundred pages rarely have crawling problems, so caching headers are a nice optimisation rather than a fix.
- Large sites with thousands of product, category or archive pages benefit more. When unchanged pages cost almost nothing to re-check, crawlers can reach new and updated pages sooner. Our explainer on when crawl budget actually matters covers where that line usually sits.
- Slow or busy servers benefit because 304 responses reduce load during crawl peaks, which can otherwise slow every response.
Be realistic about the effect. Caching headers do not make a page rank higher and they do not force a crawler to visit more often. They make each visit cheaper and more accurate.
ETag vs Last-Modified: which one to use
Both validators do the same job in different ways. Many servers send both, which is fine as long as they agree with each other.
| Header | What it contains | Strengths | Typical pitfalls |
|---|---|---|---|
ETag |
An opaque identifier for one version of the response, often a hash of the content | Precise; changes exactly when the content changes; no clock problems | Differs between servers behind a load balancer; changes on every request if it includes timestamps or random tokens |
Last-Modified |
The date and time the resource last changed | Simple, human-readable, easy to generate from a database field | Only one-second precision; often set to “now” on every request, or left at an old date after edits |
If your platform lets you pick, use a content-based ETag and add an honest Last-Modified date. If you only have one, a correct Last-Modified is far better than an ETag that changes on every request.
Common caching mistakes that hurt SEO
Most problems come from caching that is either too eager or not honest about change:
- 304 for changed pages. If the server returns 304 even after you edited the page, for example because the validator is based on a template file rather than the content, crawlers keep the old version. This is the most harmful mistake because it silently delays updates in search results.
Last-Modifiedalways equal to the current time. Many dynamic pages do this. The validator then never matches, so every request becomes a full download. It is not harmful, just wasteful.- Unstable ETags. Pages that embed a timestamp, CSRF token, random ad slot or session ID in the HTML produce a new hash on every request, which defeats validation.
- Different ETags per server. Behind a load balancer, each server may compute its own
ETagfrom file metadata. Crawlers hitting different servers see constant “changes”. - Long-lived HTML in a CDN without purging. A CDN or page cache that keeps HTML for days, without clearing it on publish, serves stale titles, prices or noindex tags to everyone, including crawlers. Our guide to CDN setup choices for SEO goes deeper on this.
- Caching error pages. A cached 500 or maintenance page served with
200 OKcan end up indexed or trigger soft 404 reports. - Dates that do not match the sitemap. If
lastmodin the XML sitemap says a page changed yesterday but the headers say it has not changed for a year, search engines learn to trust neither signal.
How to check your caching headers
You can test the whole conditional request flow from a terminal in a couple of minutes:
- Fetch the headers of a page:
curl -sI https://www.example.com/services/. Note theETag,Last-ModifiedandCache-Controlvalues. - Repeat the request with the validator:
curl -sI -H 'If-None-Match: "a1b2c3"' https://www.example.com/services/. An unchanged page should return304. - Try
If-Modified-Sincewith theLast-Modifiedvalue in the same way. - Run the first request two or three times. If the
ETagchanges each time without any edit, it is unstable. - Edit the page, clear any page cache, and run step 2 again. You must now get
200and a new validator. If you still get304, updates are being hidden. - Check a few page types: home page, article, category, product and a PDF or image, because each may be served by a different layer.
In browser developer tools, the Network panel shows the same headers and marks responses served with 304. In Search Console, the Crawl Stats report groups responses by status code, so a healthy share of 304 responses on a large site is a sign that validation works.
Setting it up on common platforms
You rarely need to write caching logic yourself. Most stacks already send validators, and the task is to confirm they behave correctly:
- Static files such as images, CSS and JavaScript: web servers like Apache and Nginx send
ETagandLast-Modifiedby default. Give versioned assets longmax-agevalues and change the file name when the file changes. - WordPress and other CMSs: HTML is generated dynamically, so validators often come from a page-cache plugin, reverse proxy or CDN. Confirm the cache is purged when a post is updated, and that the validator changes with it.
- Frameworks: many frameworks can compute a weak
ETagfrom the response body automatically. Make sure the body does not contain per-request random values. - CDNs: check whether the CDN passes your origin’s validators through or generates its own, and whether it answers conditional requests at the edge.
For HTML, a short max-age plus validators is usually the safest combination: browsers and crawlers re-check often, and unchanged pages cost almost nothing. Pair this with the ideas in our article on server response time and TTFB if pages are slow even when they do change.
How a site-wide audit helps
Caching problems are rarely visible on one page; they show up as patterns across page types. Site SEO AI Audit crawls your site like a search engine, measures server response and compression on every page, and flags status code and redirect problems, so slow or inconsistent responses stand out by template. On WordPress sites each issue comes with fix steps in wp-admin. You can start with a free audit and re-check after you change caching settings.
Related reading
- Page Weight and Compression: How to Make Pages Lighter
- XML Sitemap Best Practices: What to Include and Leave Out
- Technical SEO Monitoring: Catch Problems Before Traffic Drops
The bottom line
Send stable validators, answer conditional requests with 304 only when a page is truly unchanged, and make sure every real edit changes the ETag or Last-Modified date. Keep HTML cache lifetimes short and purge caches on publish. Done right, caching headers make every crawl visit cheaper; done wrong, they can hide your updates from search engines.
GYIK
Is a 304 Not Modified response bad for SEO?
No. A 304 simply tells the crawler that its stored copy is still current, so the page keeps its indexed content. It only becomes a problem when the server returns 304 for a page that has actually changed.
Does Googlebot use ETag and Last-Modified?
Yes. Google has documented that its crawlers support conditional requests with both ETag and Last-Modified. It recommends ETag when you can choose, because it avoids date formatting and clock problems.
Do caching headers improve rankings?
Not directly. They make crawling more efficient and can reduce server load, which helps large sites get new and updated pages crawled sooner. Rankings still depend on content, relevance and overall quality.
Should I set a long Cache-Control max-age for HTML pages?
Usually not. Long lifetimes suit versioned images, CSS and JavaScript. For HTML, a short lifetime with validators lets browsers and crawlers pick up changes quickly while unchanged pages stay cheap to check.
Why does my ETag change on every request?
The page probably contains something that differs per request, such as a timestamp, security token or random element, or several servers compute different values. Remove per-request values from the body or configure a consistent ETag.


