Post-retrieval temporal decay : how are you handling stale context in production RAG pipelines?

We’ve been running into a specific failure mode in
production RAG agents that I haven’t seen discussed
much here: temporal staleness at the retrieval layer.

The problem: standard vector search returns documents
by semantic similarity with no concept of time. A
compliance guideline from 2023 that has since been
superseded scores the same cosine similarity as the
current version. The agent ingests both with equal
confidence.

In regulated environments (clinical NLP, financial
compliance, legal), this isn’t a quality issue, it’s
a liability.

What we built to address it:

A post-retrieval middleware layer that intercepts
vector payloads before they reach the LLM and applies
deterministic temporal decay scoring:

  • decay_score (0.0 = fresh, 1.0 = fully stale)
  • domain_velocity label: hypersonic / fluid / frozen
  • days_until_stale exact integer
  • Conflict detection for contradictory sources

No LLM in the scoring layer. Pure math. Auditable.

The domain_velocity classification is the part that
surprised us most, the same 90-day-old document
should be treated completely differently depending on
whether it’s from a fast-moving regulatory domain
(hypersonic, 30-day half-life) vs fundamental
mathematics (frozen, 50-year half-life).

Questions for the community:

  1. Are you handling temporal relevance in your RAG
    pipelines at all, or relying on the LLM to reason
    about document dates?

  2. For those in regulated industries : how are you
    handling auditability of what context the agent
    was allowed to see?

  3. Is anyone doing post-retrieval filtering beyond
    basic metadata filters?

Live API for testing if anyone wants to benchmark:
api.knowledgeuniverse.tech

Happy to discuss the math behind the decay functions
if useful.

This is one of the failure modes that’s hardest to detect because every standard metric stays green while it’s happening. Retrieval precision looks fine. Relevance scores look fine. The chunks that come back actually do match the query. They just match a version of the facts that’s no longer true.

A few patterns that have worked for me, ordered roughly by cost to implement:

Stamp every chunk with freshness metadata at ingestion. Source document last-modified timestamp, source URL, chunk creation timestamp, source document version or content hash if available. This is cheap to do at ingestion and gives you the signal you need for everything downstream. The chunks themselves don’t change, but the metadata you attach gives you the lever.

Run a scheduled job that compares chunk timestamps against source document timestamps. Any chunk whose source document has been modified since the chunk was created gets flagged for re-embedding. If the source no longer exists, the chunk gets demoted or removed. This catches the most common failure mode: source was updated, embedding wasn’t refreshed, vector store is now serving stale facts.

Freshness-weighted retrieval. When you have multiple chunks matching a query, weight fresher chunks higher in the final ranking. A chunk embedded last week from a frequently-updated source should rank above a chunk embedded six months ago from the same source. Most vector databases treat all embeddings as equally current. They aren’t, and the ranking should reflect that.

Classify facts by decay rate. Not all information ages at the same speed. “The boiling point of water” doesn’t decay. “Current CEO of company X” decays over months or years. “Stock price” decays in minutes. If your corpus contains different fact types, the freshness check needs to be sensitive to that — a six-month-old chunk about chemistry is fine, a six-month-old chunk about a company’s executive team probably isn’t.

The deeper structural point: standard vector search has no concept of time. Embeddings are static once written. The corpus is alive whether you treat it that way or not. Documents change, policies update, products evolve. If your pipeline doesn’t have a way to express “this chunk was true when embedded but may no longer be true now,” every query against an outdated chunk is silently producing wrong answers with full retrieval confidence.

For production systems where stakes matter (legal, financial, medical, policy, customer-facing), freshness metadata isn’t optional. It’s table stakes.

This is one of the most precise breakdowns of the problem I have seen.

Your point about “every standard metric stays green while it’s happening” is exactly the failure mode that makes this dangerous in production. Retrieval precision looks fine because the chunks DO match the query, they just match a version of the facts that no longer exists.

Your four patterns map closely to what we implemented, with one addition that changed our results significantly:
domain-aware half-life rather than a single decay rate across the whole corpus.

A 90-day-old chunk from a regulatory compliance source should be treated completely differently from a 90-day- old chunk from a mathematics textbook. We classify every source into three velocity tiers at ingestion hypersonic (30-day half-life, things like regulatory updates and model releases), fluid (365-day half-life, clinical guidelines and ML architectures), and frozen (50-year half-life, fundamental science and standards).

The classification changes the penalty multiplier applied to the cosine score before it hits the ranking layer. A 0.94 cosine score on a hypersonic document that is 180 days old gets reduced to something that no longer outranks a 0.78 score on a fresh source.

For regulated environments specifically, the auditability requirement you mentioned is the thing most pipelines miss. You need to be able to answer “what was the agent allowed to see and when was that information validated” for every decision. The days_until_stale integer we stamp on every chunk makes that audit trail possible.

If you want to test the scoring against your own corpus the API is at api.knowledgeuniverse.tech
happy to discuss the decay math in more detail.