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]:
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_weightranges from0.0to1.0. At0.0(the default) ranking is pure similarity — identical to not passing the parameter at all. At1.0ranking is pure recency.0.3is a sensible starting point for memory use cases.recency_scoredecays exponentially with the document's age, measured from itscreated_attimestamp. Thehalf_life_daysparameter (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 document | half_life_days = 7 | half_life_days = 30 | half_life_days = 90 |
|---|---|---|---|
| 0 days (just now) | 1.00 | 1.00 | 1.00 |
| 7 days | 0.50 | 0.85 | 0.95 |
| 30 days | 0.05 | 0.50 | 0.79 |
| 90 days | 0.00 | 0.13 | 0.50 |
| 365 days | 0.00 | 0.00 | 0.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:
| Document | created_at | distance_score | recency_score | final_score (w = 0.0) | final_score (w = 0.3) |
|---|---|---|---|---|---|
| "Switch us to annual EUR billing" | 1 day ago | 0.82 | 0.98 | 0.82 (rank 1) | 0.87 (rank 1) |
| "We pay monthly in USD" | 150 days ago | 0.84 | 0.03 | 0.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
| Goal | Suggested recency_weight | Notes |
|---|---|---|
| Pure semantic search (default) | 0.0 | Recency ignored; identical to omitting the parameter. |
| Agent memory / "what's true now" | 0.2 – 0.4 | Recent observations win ties and near-ties; strong old matches survive. |
| Activity feeds, "latest first" with relevance | 0.6 – 0.8 | Recency dominates, but the query still filters and orders within a period. |
| Strict newest-first | use list with a time filter | When 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
- Filtering by time — restrict to a window with
since/until/last_n_days, which composes with recency weighting - Tuning retrieval — picking
k, score thresholds, entity and tag filters - Search & Retrieval API — full reference for every parameter and field