# Rank newer documents higher with the recency reranker

> Agno's new RecencyReranker blends the search score with an exponential time decay, so a current policy or doc outranks the revision it replaced. It works best on PgVector.

- Published: 2026-09-23
- Author: Sannya Singal
- Categories: Changelog
- Canonical: https://www.agno.com/articles/rank-newer-documents-higher-with-the-recency-reranker
- Markdown: https://www.agno.com/articles/rank-newer-documents-higher-with-the-recency-reranker.md

Agno's new `RecencyReranker` gives `Knowledge` search a sense of time, which vector search lacks. Update your travel policy, and the old version still matches questions about travel just as well, sometimes better. Your agent then quotes last year's meal limit.

`RecencyReranker` blends each result's relevance with an exponential decay on its timestamp:

```text
score = (1 - weight) * relevance + weight * exp(-ln2 * age / half_life_days)
```

It tilts the ranking toward newer documents, and an older document that is clearly more relevant still wins. `weight` sets how much freshness counts, from 0.0 for relevance only to 1.0 for age only. It defaults to 0.3. `half_life_days` sets how fast freshness fades and defaults to 30 days.

```python
from agno.knowledge.knowledge import Knowledge
from agno.knowledge.reranker import RecencyReranker

knowledge = Knowledge(
    vector_db=vector_db,
    reranker=RecencyReranker(half_life_days=365),
)
knowledge.insert(
    name="Travel expense policy 2025",
    text_content="Expense policy update: the daily travel meal limit is now 75 USD.",
    metadata={"updated_at": "2025-09-01"},
)
```

![The query "What is the daily meal limit when travelling?" against PgVector, top 2 results, real output. Plain vector search ranks Travel expense policy 2023 first with 0.884 and the 2025 policy second with 0.862. RecencyReranker with half_life_days 365 ranks the 2025 policy first with 0.746 and the 2023 policy second with 0.642.](https://www.agno.com/images/v3-0-11-recency-reranker.png)

`RecencyReranker` reads each document's date from `updated_at` in its metadata, as an ISO-8601 string, a datetime, or epoch seconds or milliseconds. If a document has none, PgVector can supply one: build it with `return_updated_at=True` and it reports when each row was stored. Re-ingesting a document under the same name makes it fresh again. The option is off by default because the timestamp travels in metadata your model can see. Documents with no timestamp at all rank on relevance alone.

Two PgVector fixes came with it. Upserts now write `updated_at`, which only `update_metadata()` used to set. Keyword search now returns a normalized relevance score, so vector, keyword and hybrid search all report scores on one scale.

`RecencyReranker` runs on the [knowledge retrieval pipeline](https://www.agno.com/articles/rerank-knowledge-search-on-any-vector-database), so it works with any vector database that returns relevance scores and timestamps. PgVector is the one it's built and tested against.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/07_knowledge/02_building_blocks/11_recency_boost.py), and learn more about the [recency reranker](https://docs.agno.com/reference/knowledge/reranker/recency) and [reranking](https://docs.agno.com/knowledge/concepts/search-and-retrieval/reranking) in the documentation.
