Guides

Recency-weighted ranking

Bias search results toward recent documents with a single recency_weight parameter — so yesterday's note about a customer outranks a vague mention from six months ago, without throwing away semantic relevance.

By default, search ranks purely by semantic similarity: a six-month-old transcript and yesterday's compete on equal footing. For agent-memory and longitudinal use cases that is almost always wrong — the recent observation is usually the one you want. recency_weight lets you blend a recency signal into the ranking, server-side, with no extra ML and no measurable latency cost.

This is a re-ranking of the candidates the search already found — it never changes which documents match your filters, only the order of the top results. To restrict results to a window instead of just nudging the order, use the time filters (since / until / last_n_days); the two compose.


How the score is computed

For each candidate hit, the server blends two scores in [0, 1]:

text
distance_score = cosine similarity of the matched passage, in [0, 1]
recency_score  = exp(-age_days / half_life_days)
final_score    = (1 - recency_weight) * distance_score
               +      recency_weight  * recency_score
  • recency_weight ranges from 0.0 to 1.0. At 0.0 (the default) ranking is pure similarity — identical to not passing the parameter at all. At 1.0 ranking is pure recency. 0.3 is a sensible starting point for memory use cases.
  • recency_score decays exponentially with the document's age, measured from its created_at timestamp. The half_life_days parameter (default 30) sets how fast: at one half-life the recency contribution is halved, at two half-lives it is a quarter, and so on.

Recency score by age

How recency_score falls off for a few half-lives:

Age of documenthalf_life_days = 7half_life_days = 30half_life_days = 90
0 days (just now)1.001.001.00
7 days0.500.850.95
30 days0.050.500.79
90 days0.000.130.50
365 days0.000.000.06

A short half-life (7 days) is aggressive — only the last week or two carries weight. A long half-life (90 days) decays gently across a quarter. Pick the window that matches how quickly your domain goes stale.


Worked example

Two documents match the query "what does the customer want for billing?" equally well on semantics, but one is from yesterday and one is from five months ago. With half_life_days = 30:

Documentcreated_atdistance_scorerecency_scorefinal_score (w = 0.0)final_score (w = 0.3)
"Switch us to annual EUR billing"1 day ago0.820.980.82 (rank 1)0.87 (rank 1)
"We pay monthly in USD"150 days ago0.840.030.84 (rank 1)0.60 (rank 2)

At recency_weight = 0.0 the older, very slightly closer match wins — and your agent tells the customer something that stopped being true months ago. At recency_weight = 0.3 the fresh document is promoted to the top, while a strong-enough old match would still hold its place. Recency nudges; it does not blindly sort by date.


Using it

recency_weight and half_life_days are accepted on the search endpoints. SDK users building an agent-memory layer get the same behavior through the Memory facade's recall(recency_weight=...), which is tuned for exactly this case.

# Server-side recency blend on the REST search endpoint
curl "https://api.aetherdb.ai/search?q=billing%20preferences&k=5&recency_weight=0.3&half_life_days=30" \
  -H "Authorization: Bearer $AETHER_API_KEY"

Recency re-ranks; time filters restrict

recency_weight re-orders the candidates that already matched your query and filters — it never drops a document. When you want to exclude anything older than a cutoff, combine it with a time filter: last_n_days=90 bounds the window (a hard pre-filter), and recency_weight=0.3 then biases what's left toward the most recent. The two are complementary.


Choosing a weight

GoalSuggested recency_weightNotes
Pure semantic search (default)0.0Recency ignored; identical to omitting the parameter.
Agent memory / "what's true now"0.20.4Recent observations win ties and near-ties; strong old matches survive.
Activity feeds, "latest first" with relevance0.60.8Recency dominates, but the query still filters and orders within a period.
Strict newest-firstuse list with a time filterWhen you don't want similarity in the ranking at all, list by recency instead of searching.

Out-of-range values are rejected: recency_weight must be in [0.0, 1.0] and half_life_days must be greater than 0, otherwise the request returns 400.


Next steps