I was watching Perplexity cite a three-year-old article from a competitor ahead of my updated one, and I could not figure out why. My post was newer, longer, and more accurate. The competitor's was outdated but kept getting cited first.
The difference was freshness signaling. My page had a datePublished in JSON-LD and nothing else. The competitor had datePublished, dateModified, an "Updated on" byline, and article:modified_time in their OG tags — all three pointing at a recent refresh. The AI engine read that and treated their stale content as fresh. I added the same three signals to my post, truthfully, and the citation flip happened within a week.
Why Freshness Matters to AI Citation Engines
Search engines have weighted freshness for fifteen years. AI answer engines weight it harder, because the cost of citing stale information is public and embarrassing. When ChatGPT, Perplexity, or Claude cites a claim that has since changed, the user sees a wrong answer attributed to your URL. The engine learns.
So the retrieval layer heavily favors content that broadcasts a recent update. Not just "published recently" — that decays fast — but "actively maintained." A post from 2022 with a verified 2026 update beats a post from 2024 that has sat untouched.
The catch: the engines need to verify the update, not just take your word for it. That is why the three-layer signal exists. Each layer corroborates the other two.
Layer One: dateModified in JSON-LD
This is the machine-readable canonical. Schema.org's Article and BlogPosting types accept both datePublished and dateModified as ISO 8601 timestamps:
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "The Updated Guide to Widget Configuration",
"datePublished": "2023-08-14T10:00:00-06:00",
"dateModified": "2026-04-18T09:30:00-06:00",
"author": {
"@type": "Person",
"name": "Jane Smith"
}
}
Both fields should be present, and dateModified should be equal to or later than datePublished. If a page has only datePublished, some engines infer dateModified = datePublished and treat the content as never having been updated.
Layer Two: Visible "Updated On" Stamp
This is the human-readable corroboration. Somewhere visible in the article — usually next to or just below the byline — a line that says:
<p class="meta">
Published <time datetime="2023-08-14">August 14, 2023</time>
· Updated <time datetime="2026-04-18">April 18, 2026</time>
</p>
The <time> element with a datetime attribute is the important part. It gives crawlers and parsers a machine-readable hook inside human-readable text. The surrounding words can be anything — "Updated," "Last revised," "Refreshed" — but the <time> tags need to be there.
Why this matters: if your JSON-LD says one thing and the visible page says nothing, an AI engine that cross-checks the two will discount the JSON-LD. The engines got burned too many times by sites that set dateModified to the current day on every page at build time with no actual content change. A visible stamp that matches the JSON-LD is the evidence that the update is real.
Layer Three: article:modified_time OG Meta
The third signal lives in Open Graph metadata:
<meta property="article:published_time" content="2023-08-14T10:00:00-06:00">
<meta property="article:modified_time" content="2026-04-18T09:30:00-06:00">
OG tags are what social platforms read when a URL is shared, but they are also what Facebook's crawler, LinkedIn's crawler, and a surprising number of AI retrievers read for article metadata. The article:modified_time field is the third independent attestation that the content is fresh.
Three sources, same timestamp, same page. That is a freshness signal an AI engine will trust.
dateModified vs datePublished: The Distinction That Matters
datePublished is when the URL first went live with content. It never changes. You do not update it when you refresh the post. Updating it is lying about the publication date, which is how Google News stops trusting a site.
dateModified is when the content was materially updated. "Materially" is the word that matters. Fixing a typo is not a material update. Rewriting a section, adding new data, updating a statistic, replacing a broken code example — those are material updates. Rebuilding the site with a new CSS file is not.
The test I use: could a reader who read the original version and the new version tell the difference in the content itself? If yes, update dateModified. If no, leave it alone.
How to Avoid Gaming It
The single biggest mistake I see: sites that set dateModified = build_time on every page at every deploy. That makes every page look freshly updated every time CSS changes. AI engines detect this pattern and discount the signal on the whole domain.
The fix is simple: dateModified should come from the content's own frontmatter, not from the build system. In Eleventy:
---
title: "The Updated Guide to Widget Configuration"
date: 2023-08-14
updated: 2026-04-18
---
Then reference updated explicitly in the template. If the frontmatter field is missing, fall back to date, not to Date.now(). The page shows no modification only when there is none — which is the honest signal.
Where the Analyzer Flags This
The site analyzer at /tools/mega-analyzer/ checks all three layers on article-type pages:
- JSON-LD Article or BlogPosting with
dateModifiedpresent and ISO 8601 valid. - Visible updated timestamp detected in the rendered DOM (looking for
<time>elements or common "Updated" patterns). article:modified_timeOG meta tag present.
Missing any one gets flagged as an AEO freshness issue. Missing all three on an article-type page is a hard flag — the page is effectively dateless to retrieval engines that rely on these signals.
The Edge Case: Evergreen Pages
Pages that are genuinely evergreen — a glossary entry, a reference doc, a contact page — should still have dateModified, and it should reflect the last actual edit. The value of an evergreen page is that it has not needed to change. A dateModified from two years ago on a reference page is not a penalty. It is a statement that the information has been stable, which is itself a quality signal.
Do not touch dateModified on evergreen pages to make them look fresh. The signal only works if it is honest.
The Short Version
- Three freshness signals, three locations: JSON-LD
dateModified, visible<time>stamp,article:modified_timeOG meta. - All three point to the same timestamp, and all three reflect a real content update.
datePublishednever changes.dateModifiedonly changes when the content itself materially changes.- Build systems that stamp every page with
Date.now()on deploy poison the signal and get detected. - Run the check at
/tools/mega-analyzer/on any article-type page to confirm all three layers are present.