Insights

Sitemap lastmod — Why Fake Dates Backfire

The lastmod field in a sitemap tells search engines when a page last changed. Learn why identical or invented dates make search engines ignore the field, how we derive ours from version control, and the build trap that nearly undid it.

Purushottam Kumar Suman
Purushottam Kumar SumanSeptember 14, 20269 min read
Founder & CEO, DeepSync
XML sitemap with lastmod dates

Short answer: lastmod should state when a page's content last meaningfully changed. Search engines use it only when it proves reliable. If every URL shows the same date, or the date moves every time you deploy, the field is treated as noise and ignored. Derive it from real change history, and leave it out for pages where you do not know.

Table of Contents

  1. What lastmod Is For
  2. Three Ways It Goes Wrong
  3. What We Had
  4. Deriving Dates From Version Control
  5. The Build Trap
  6. Rules for an Honest lastmod
  7. Key Takeaways

What lastmod Is For

A sitemap lists the URLs you want crawled. For each, you may include a last-modified date:

<url>
  <loc>https://example.com/pricing</loc>
  <lastmod>2026-09-14</lastmod>
</url>

The intended use is scheduling. A crawler that knows a page changed yesterday can revisit it sooner, and one that knows a page has not changed in a year can leave it alone.

Google has said publicly that it uses lastmod when the value is consistently accurate, and that it ignores the changefreq and priority fields. So lastmod is the one optional field with real effect, and only when it can be trusted.

Three Ways It Goes Wrong

PatternWhat it looks likeResult
Uniform datesEvery URL has the same dateCarries no information
Build-time datesEvery URL shows today's date after each deployClaims the whole site changed, repeatedly
Invented datesDates adjusted to appear freshContradicted when the crawler finds unchanged content

In each case the crawler compares the claim with what it finds. When the claim keeps being wrong, the sitemap's dates stop being used. An inaccurate lastmod is worse than none, because it spends the trust that would have made a real update noticeable.

What We Had

Our sitemap generator had a single hardcoded date on every blog entry. Fifty articles, one date, set when the first batch was published and never touched again.

It was the first pattern in the table. It was also the easiest kind of bug to miss: the sitemap was valid, the dates were plausible, and nothing complained.

When we noticed, an idea came up that is worth recording because it is tempting: assign varied dates to the entries so the sitemap would look naturally updated. We decided against it. Varied invented dates are still invented. They would have produced exactly the mismatch between claim and content that leads crawlers to discount the field, with extra effort.

The better question was whether we already knew the real dates. We did.

Deriving Dates From Version Control

Every page on the site is backed by a file in the repository, and version control records when each file last changed. So the build asks, for each page, for the date of the last commit that touched its source file.

The mapping:

  • Blog articles: one Markdown file each, so one date each.
  • Industry pages: one content module each.
  • Sections backed by a single shared file, such as documentation: the section's date comes from that file, and its child pages inherit it.
  • Top-level pages: the route file.

A small script runs before the build and writes a map from URL path to date. The sitemap reads the map.

The result was genuinely varied dates, because the pages genuinely changed at different times. Several distinct dates across nearly two hundred URLs, each one true. Where many pages share a date, that is accurate too: they were last edited together. Uniform dates are fine when they are real.

One rule we kept: if no date can be determined, the entry has no lastmod. A missing value is honest. A guessed one is not.

The Build Trap

This nearly reintroduced the problem.

Our deployment service builds the site from a shallow clone of the repository: it fetches only the latest commit, to save time. That is common in hosted build systems.

In a shallow clone, the history is one commit deep. Ask version control when any file last changed, and the answer is that one commit, for every file. Run the date script there and it stamps the deploy date on all two hundred pages. That is the build-time pattern from the table, produced by a tool that works correctly on a developer's machine.

The fix has two parts.

  1. The script detects the situation and does nothing. It checks whether the repository is shallow, and whether there is enough history to be meaningful. If not, it exits without writing.
  2. The generated date map is committed to the repository. It is produced on a machine with full history and checked in. The deployment build uses the committed file as it is.

Generated files are normally kept out of version control, so this looks wrong at first glance. Here it is deliberate, and there is a comment saying so, because the obvious "clean-up" would break it.

The general lesson: a value derived from your environment is only as good as the environment it runs in. Check what your build system actually has access to.

Rules for an Honest lastmod

  1. Use the date content last meaningfully changed. Not the build date, not the deploy date.
  2. Ignore trivial edits where you can. A typo fix is not an update worth announcing.
  3. Derive it automatically from a real source: version control, a CMS's modified timestamp, or a database field.
  4. Omit it when unknown.
  5. Never set it to "now" by default.
  6. Keep it consistent with the page. The visible date, the structured data dateModified, and the sitemap lastmod should tell the same story (schema markup).
  7. Test in your real build environment, not only locally.
  8. Skip `changefreq` and `priority`. They are ignored by Google.

Check your sitemap for one repeated date

Open your sitemap and count the distinct lastmod values. If there is one, or if every value is today, the field is not doing anything for you.

Key Takeaways

  • lastmod works only when it is accurate.
  • Uniform, build-time, and invented dates all cause it to be ignored.
  • Derive dates from version control or your CMS, and omit them when unknown.
  • Check what your build environment can see; shallow clones give every file the same date.

Conclusion

A sitemap date is a small promise to a crawler. Keep it and your real updates get noticed. Break it and you lose the one optional field that does anything.

The trailing-slash bug on the same site.

Frequently Asked Questions

Was this article helpful?

Ready to understand
users like never before?

Join thousands of teams who use DeepSync to uncover insights,improve experiences, and build better products—faster.

Quick & easy onboarding
See results in real time
Enterprise-grade security