Blog · 2026-08-30
When Your Sitemap lastmod Lies Every Day, Google Stops Listening: The Content Hash State Machine
Static sites that stamp lastmod with the build time on every rebuild are lying to Google daily. The fix is to strip the noise, hash the content, and run a state machine so the date only moves when the content actually changed.
Open your own sitemap.xml and every lastmod across hundreds of URLs is the same minute this morning, because the deploy schedule just ran. Not a word of content changed. The only thing that changed is the build time. A sitemap like this shouts "the whole site was updated" at Google every single day, and after a while, even the one page you genuinely updated is not worth its time. This is not an exotic failure, it is the default behavior of most static site generators.
The Symptom: One Timestamp Across Every lastmod on the Site
Diagnosis takes one look. Open the sitemap, and if every <lastmod> carries the same timestamp and that timestamp happens to match the last deploy, your generator is almost certainly using "now" as the modified time, either date.today() shoved into dateModified or a build script overwriting lastmod with the build moment. A second piece of evidence sits in Search Console: the sitemap shows as read, yet the pages you actually edited never get recrawled.
This is worst on sites that rebuild on a schedule. We maintain a 402-page sports content site that rebuilds 4 times a day (standings and fixtures change daily, so the rebuilds are necessary). Using the build time as lastmod would mean claiming every day that every page "was updated 4 times", when the body copy on most of them has not moved a single byte. Worse, the same lie usually gets told twice: once in the sitemap, and again in the page's structured data dateModified.
Google's Position: An Inaccurate lastmod Is Treated as Absent
Google's official sitemap documentation is blunt about it: lastmod is only used when it is "consistently and verifiably accurate", verified for example by comparing it against the page's actual modifications. The same document also defines what counts as an update worth flagging: changes to the main content, structured data, or the page's links. Bumping a copyright year does not count.
The purpose of lastmod is to help crawlers prioritize, telling them "crawl these pages first, skip the rest". Shout "updated" across the whole site every day and that signal drops to zero. Google has no way to tell which page actually changed, and you have thrown away the most valuable crawl hint you had, with your own hands. For a site that rebuilds several times a day and wants its updates indexed quickly, that is shooting yourself in the foot.
The Fix: A Content Hash State Machine, Dates That Follow the Content
The principle in one line: lastmod should not come from "when it was built", it should come from "when the content changed". The method is to keep a state file for each page that survives across builds:
{ "/match/group-a/": {
"hash": "3f2a…",
"publishedAt": "2026-06-10",
"updatedAt": "2026-08-12" } }
Every build runs the same procedure on every page:
- After the HTML is generated, extract the main content, normalize it, and compute a SHA256.
- Page not in the state file, so it is new: write today into both publishedAt and updatedAt.
- Hash matches last time: change nothing, keep the old dates.
- Hash differs: set updatedAt to today and write it back to the state file.
The sitemap lastmod, the structured data dateModified and the "last updated" line shown on the page all read from the state file, so three places share one source of truth. The state file travels with the repository or the deploy artifact, so no number of rebuilds gives it amnesia. Think through when you write it back too: only persist once the deploy is confirmed successful. A failed build must not be allowed to pollute the state, or one blown build drags every date on the site down with it.
Strip It Clean Before Hashing: Scripts and Tracking Code Are Not Content
Where this mechanism usually dies is a hash computed too coarsely. Hash the whole HTML document and you will find that every page "changed" on every build: a tracking snippet gets a new version, asset filenames carry cache fingerprints (app.a1b2c3.js), nonces are random, the footer auto-prints the current year. Move any one of those and every hash on the site turns over, leaving the state machine useless. By the same logic, a "related articles" block that picks entries at random on each build has to be excluded from the hash range too.
So strip before you hash. Use a real HTML parser (not a regular expression) to remove <script>, <style> and comments entirely, clear out tracking parameters and version fingerprints, keep only the text and structure of the main content area, and normalize whitespace before computing. What you strip out is exactly what Google's definition does not count as a significant update. Cut the hash boundary along the official boundary for significant.
Published Date and Updated Date Are Two Fields, Do Not Merge Them
Another common mistake is having only one date field for the whole site. The published date (publishedAt) should never move once written. The updated date (updatedAt) moves only when the hash changes. The output rule fits on one line:
lastmod = updatedAt ?? publishedAt
For a page that was never edited, lastmod honestly stays on the publish date, and there is nothing embarrassing about that. For a page that really was edited, lastmod points precisely at that day, and that is where the value is.
Acceptance requires negative testing, and both conditions have to pass: run two builds back to back, and the second must report zero pages changed. Then edit one paragraph on one page, and only that page's lastmod may move. Fail either one and the noise is not fully stripped, which means your sitemap is still lying.
Closing
lastmod is your line of credit with crawlers, and credit is built by not moving things around. Tie the date to a content hash and lying is removed from the process itself, by mechanism rather than by self-discipline. If your site is also a few hundred pages rebuilding on a daily schedule while the sitemap has never once made Google look properly, this is the state machine running on the content site we operate ourselves. Come talk to us.
We Turned This Kind of Detail Into a Service
lastmod honesty is the sort of metric nobody checks, but the moment someone does check it, they can tell whether the work was done properly. Our own site's sitemap is produced by a content hash state machine, and the date only moves when something changed.
- Site architecture and technical SEO: sitemap, canonical tags, robots and structured data aligned in one pass
- Index monitoring: indexing status page by page, with IndexNow pushed to all five endpoints
- Content production: lastmod only means something when there is a real update
| Plan | Price | What is included |
|---|---|---|
| Build | $900 USDT | Site architecture, technical SEO, initial content |
| Monthly maintenance | $400 USDT / month | Content production, internal link maintenance, index monitoring |
Specs are on iGaming SEO Site Build.
We solve this kind of problem every day
Describe your situation and we will tell you straight whether it is doable and roughly what it costs.
Chat on Telegram