How to Keep a RAG Index Fresh (Staleness Bounds, Not Vibes)
Freshness as an engineered property: per-source staleness contracts, document versioning and tombstones, effective-date filtering, deletion propagation with reconciliation backstops, and the sync-lag metrics that predict stale answers before users report them.
- Freshness is a per-source contract, not a global setting: every connector declares a maximum acceptable staleness ('this source is never more than N hours behind'), and the pipeline measures actual sync lag against that bound so drift alarms before users notice wrong answers.
- Version documents explicitly and tombstone superseded ones — otherwise two generations of the same policy sit side by side in the index and the generator blends them into a confident contradiction.
- Index validity windows with the chunk (effective-from / effective-until metadata) so time-sensitive material is excluded mechanically at query time instead of by prompt hope.
- "Time since last successful sync" per source is the single most predictive freshness metric — it forecasts stale-answer complaints weeks before feedback arrives, and it is cheap to compute from ingestion checkpoints you already have.
The pillar guide names the stale answer as RAG's most insidious failure: the system looks completely healthy while being confidently wrong, citing a policy that was replaced or a price that changed. Nothing about the serving path looks broken — the fluency of the output hides the age of its evidence. This article turns freshness from a hope into an engineered property.
What does a freshness contract look like?
Every source gets an explicit staleness bound written next to its connector configuration: transactional systems might commit to near-real-time lag, wikis to hourly, crawled web sources to daily. Three parts make the contract real:
- A declared bound per source — the number the business would defend ("pricing changes must appear within 15 minutes")
- Measured actual lag — time since last successful sync per source, computed from ingestion checkpoints
- An alarm on divergence — actual exceeding bound pages someone, even if the site looks fine
Teams that skip the declaration cannot detect violations, because there is nothing to violate. The bound also drives design: a 5-minute bound requires change feeds; a daily bound makes scheduled crawls with hash-based diffing perfectly adequate (the ingestion guide covers both).
How do versioning and tombstones keep old truth out?
Every document carries a version identity, and ingestion treats "new version arrived" as supersede-and-tombstone, not append:
- The new version's chunks enter the index with the current version marker
- The old version's chunks are flagged tombstoned — excluded from retrieval, retained for audit
- Reconciliation sweeps periodically compare source inventories against the index and tombstone anything missing upstream, catching the deletions that never sent events
Without this, two generations coexist retrievably, and the generator — asked about the policy — helpfully synthesizes both into fluent nonsense. Version markers also make rollback possible after a bad ingestion run, which is otherwise indistinguishable from corruption.
Where do effective dates fit?
Some content is indexed before it is true (announcements under embargo, seasonal pricing, phased rollouts) or stops being true on a schedule (contracts, certifications). Store validity windows as chunk metadata — valid_from and valid_until — and enforce them as pre-filters at query time. Mechanical exclusion beats prompt instructions for the same reason permission filters do: retrieved text can argue with instructions, but it cannot argue with a filter.
What does the ingestion-side machinery look like?
Four mechanisms carry the contract, and each maps to a failure it prevents:
- Change feeds for push-capable sources — near-real-time propagation without polling load; the bound can be minutes
- Scheduled crawls with content hashing — for poll-only sources, skipping unchanged documents so the crawl budget concentrates on actual change
- Tombstone writes on supersede/delete — explicit markers that retrieval filters respect, plus audit retention
- Reconciliation sweeps — periodic inventory comparison (source list versus index list) as the backstop that catches silent removals
Underneath all four sits the same durability story as any pipeline: resumable batches, retry with backoff on rate limits, dead-letter isolation of poison documents. A freshness program running on top of a fragile pipeline measures its own failures faithfully and still cannot fix them — durability comes first (durable execution, retries).
Which metrics predict stale answers before they happen?
Four numbers, all derivable from infrastructure you already run:
- Sync lag per source versus its declared bound — the leading indicator
- Reconciliation mismatch count — how often inventory comparison finds un-deleted ghosts
- Tombstone ratio over time — a sudden spike means an upstream reorganization your connectors may be mishandling
- Oldest unsynced event age in queue-backed pipelines — catches stuck consumers that dashboards average away
Route these into the same observability surface as latency and error rate (agent observability), because operationally a stale corpus IS an outage — just one with better manners.
How does freshness interact with agent memory?
When agents are the consumers, freshness gets a second dimension: session-level facts and task state age differently from corpus knowledge and belong in different stores with different invalidation rules (agent memory & context). A conversation summary should never masquerade as corpus fact — keep volatile conversational state out of the indexed layer entirely, so corpus staleness bounds stay meaningful.
Handled this way, freshness stops being the failure everyone dreads and becomes what it is everywhere else in production systems: a measured SLO with alerts, dashboards, and boring postmortems.
A closing note on scope discipline: freshness work scales down as well as up. A corpus of five sources needs one page of contract — bounds, tombstones, one reconciliation cron — not a platform. The mistake to avoid is neither over-building nor skipping, but leaving the bounds implicit: an undeclared expectation ("the index should be current") cannot be met, measured, or defended. Write the numbers down; the rest follows.
For teams wanting a starting template, the minimal viable freshness program fits on one page: a table of sources with declared bounds; a scheduled job computing sync lag per source and comparing it to those bounds; version markers plus a tombstone flag in the chunk schema; one reconciliation sweep per week per source class; and an alert rule that fires when lag exceeds bound or reconciliation finds ghosts. Every element above scales independently later — more sources, tighter bounds, faster sweeps — without changing the shape.
Finally, wire freshness into the answer surface itself. When staleness bounds are metadata, the system can annotate answers with evidence age — "per pricing synced 4 minutes ago" — which converts user trust from blind faith into an inspectable property. The same metadata powers targeted questions ("only quote documents updated this quarter") for use cases with tighter recency needs than the global bound provides. Freshness metadata is cheap at ingest and pays out everywhere downstream; its absence is felt everywhere too.
Frequently asked questions
- How stale is too stale for a RAG corpus?
- It depends on the source, which is exactly why staleness bounds are declared per source rather than globally. Pricing and policy content may tolerate minutes; product documentation days; historical reference material months. The engineering move is writing the bound down per connector, measuring real lag against it continuously, and treating bound violations as incidents even when no user has complained yet.
- What is a tombstone in a RAG index?
- A marker on an indexed chunk saying the upstream document was deleted or superseded. Tombstoned content stays physically present (for audit or rollback) but is excluded from retrieval results by filter. Tombstones matter because deletions are silent upstream — a removed document simply stops sending update events — so without explicit markers or reconciliation sweeps, removed content keeps answering.
- Should I delete old versions of documents from the index?
- Exclude them from retrieval, but not necessarily from storage. Superseded versions are useful for audit trails, diffing what changed, and rolling back bad updates. The correctness requirement is that only the currently-valid version is retrievable — typically enforced with a version flag or valid-window metadata that query-time filters respect.
- How do I handle content that becomes true later (embargoed announcements)?
- Index effective dates alongside the chunk — valid-from and valid-until where applicable — and filter at query time against them. An announcement indexed today with an effective date next week stays out of results until the window opens, mechanically. This beats prompt-level instructions ("ignore future-dated content") because filters cannot be argued with by a persuasive paragraph.
This guide is free and stays free. The reference corpus behind it — machine-readable contracts, verified primary sources, continuously refreshed — is the paid product: a €5 starter key unlocks every premium reference for one agent via API; a €25 corpus license delivers the full corpus as RAG / fine-tuning data with an explicit AI-use grant; the €150 enterprise license adds commercial redistribution rights.