Skip to content

Getting sitemap lastmod right (and why yours is probably wrong)

lastmod is the most useful and most commonly broken field in an XML sitemap. What it should mean, what breaks it, and how to check yours.

· 3 min read · Index-now

lastmod tells a search engine when a page's content last meaningfully changed. Used correctly it is the single most efficient signal in your sitemap. Used incorrectly — which is the common case — engines learn to ignore it entirely.

What it is supposed to mean

The date the content last changed in a way that matters to a reader. Not the last deployment, not the last cache rebuild, not the last time anything in your database touched the row.

The three ways it goes wrong

1. Every URL shows today's date

The most common failure by far. A static site generator rebuilds everything on every deploy and stamps the build time onto every page. A CMS writes updated_at on any row change, including view counters.

The effect: the engine sees your entire site "change" daily, discovers that nothing actually did, and stops trusting the field. You have then lost the signal for the pages that genuinely did change.

2. It never changes

The opposite failure — a hardcoded date, or a field that was populated once at import and never updated. Equally useless, and it can suppress recrawling of pages that did change.

3. It is in the wrong format

The sitemap protocol requires W3C Datetime. Valid: 2026-08-09 or 2026-08-09T14:30:00+00:00. Invalid: 09/08/2026, Aug 9 2026, or a bare Unix timestamp. Malformed dates are ignored, silently.

How to check yours in thirty seconds

Fetch your sitemap and look at the distribution of dates:

curl -s https://example.com/sitemap.xml | grep -o '<lastmod>[^<]*' | sort | uniq -c | sort -rn | head

If one date accounts for most of your URLs, and that date is today or your last deploy, your lastmod is broken. A healthy distribution is spread across months, clustering on days you actually published.

Fixing it

Track content changes separately

Keep a dedicated content_updated_at column, distinct from Eloquent's or ActiveRecord's updated_at. Update it only when fields that affect the rendered page change — title, body, price, images — and not when view counts, cache keys or internal flags move.

Be conservative

If you are unsure whether a change was meaningful, leave the date alone. An occasionally stale lastmod costs you one delayed recrawl. A permanently noisy one costs you the signal entirely.

Never set it in the future

Timezone bugs produce this regularly. A future date is a clear sign of a broken generator and is treated accordingly.

Why this matters beyond sitemaps

Any change-detection system built on your sitemap inherits its quality — including IndexNow automation. A sitemap that claims everything changed today either causes the whole site to be resubmitted daily, burning quota and risking rate limits, or forces the tooling to ignore lastmod and fall back to fetching and fingerprinting pages, which is slower and less precise.

Well-behaved tooling should detect and ignore blanket-rewritten dates rather than acting on them. But the better fix is at the source: emit dates that mean something, and every downstream system gets more accurate.

What about changefreq and priority?

Both are effectively ignored by major search engines and have been for years. Google has said so explicitly. Setting every page to priority 1.0 and changefreq daily achieves nothing except a larger file. lastmod is the field worth your attention.

Keep reading

Stop waiting to be found

Set it up once. We keep telling the search engines about every change you make, for $12 a year.