Skip to main content
Go to documentation:
⌘U
Weaviate Database

Develop AI applications using Weaviate's APIs and tools

Deploy

Deploy, configure, and maintain Weaviate Database

Query Agent

Run agentic search over your Weaviate Cloud collections

Weaviate Cloud

Manage and scale Weaviate in the cloud

Engram

Persistent memory for LLM agents and applications

Additional resources

Integrations
Contributor guide
Events & Workshops
Weaviate Academy

Need help?

Weaviate LogoAsk AI Assistant⌘K
Community Forum

Boost

Preview — added in v1.38

This is a preview feature. The API may change in future releases.

Boost soft-ranks search results — promote or demote matching documents without removing them from the result set. Matching documents move up. Non-matching documents stay in the results but rank lower.

Apply boost to vector, hybrid, BM25, near-text, near-vector, near-object, and aggregate queries.

How it works

A boost is a post-retrieval rescorer:

  1. The primary search (vector, hybrid, BM25, ...) fetches depth candidate results. Set depth higher than offset + limit if you want boost to consider candidates beyond the first page.
  2. The boost scorer rescores those candidates in memory by evaluating each condition per candidate, normalizing per result set, and blending with the primary score. There are no new index queries — the cost is per-candidate in-memory scoring, not extra shard fan-out. Both primary and boost scores are min-max normalized into [0, 1] before blending, and the final score is renormalized to [0, 1].
  3. The user's original offset and limit are applied after the re-sort.

Condition types

A boost is one or more conditions, blended into a single rescore. Every condition is one of: filter, property value, time decay, or numeric decay.

Filter condition (soft WHERE)

Score is 1 if the result matches the filter, 0 if not. Non-matching documents stay in the result set but rank lower than matching ones. Supported filter operators: Equal, NotEqual, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, And, Or, Not. (Like, IsNull, geo operators, and ref-path filters are not supported in boost conditions.)

py docs  API docs
More infoCode snippets in the documentation reflect the latest client library and Weaviate Database version. Check the Release notes for specific versions.

If a snippet doesn't work or you have feedback, please open a GitHub issue.
# Promote articles in the "research" category without filtering others out.
response = articles.query.near_text(
query="transformer architectures",
limit=5,
boost=Boost.filter(
Filter.by_property("category").equal("research"),
weight=0.5,
),
return_properties=["title", "category"],
)

for o in response.objects:
print(o.properties["category"], "-", o.properties["title"])

Property-value condition

Continuous score proportional to a numeric property's value (likes, downloads, popularity, ...). The raw value is optionally modified, then min-max normalized to [0, 1] across the result set.

The name argument is required, only numeric properties (int, number) are supported.

ModifierEffectWhen to use
NONE (default)score = valueValues in a narrow range.
LOG1Pscore = log(1 + value)Long-tail dampening (e.g. download counts from 5 to 5_000_000).
SQRTscore = sqrt(value)Milder long-tail dampening.
py docs  API docs
More infoCode snippets in the documentation reflect the latest client library and Weaviate Database version. Check the Release notes for specific versions.

If a snippet doesn't work or you have feedback, please open a GitHub issue.
# Bias toward articles with more `likes`. LOG1P dampens the long tail so a
# single 5-million-likes outlier doesn't dominate.
response = articles.query.near_text(
query="transformer architectures",
limit=5,
boost=Boost.property(
"likes",
modifier=Boost.Modifier.LOG1P,
weight=0.7,
),
return_properties=["title", "likes"],
)

for o in response.objects:
print(o.properties["likes"], "-", o.properties["title"])

For "closer to a specific value is better" instead of "higher is better", use numeric decay below.

Time decay

Continuous [0, 1] score that decays with distance from an origin time. The canonical use case is "boost more recent documents".

ParameterRequiredNotes
propertyYesName of a date property.
originNo"now" (default), a datetime, or an ISO string.
scaleYesDistance at which the score equals decay. Accepts a timedelta or duration string ("7d", "6h", "30m").
offsetNoDistance below which the score is exactly 1. Default 0.
curveNoEXPONENTIAL (default), GAUSSIAN, or LINEAR. See Curves below.
decayNoScore at scale distance. Default 0.5. Range (0, 1].
py docs  API docs
More infoCode snippets in the documentation reflect the latest client library and Weaviate Database version. Check the Release notes for specific versions.

If a snippet doesn't work or you have feedback, please open a GitHub issue.
# Score decays exponentially over time. "30d scale" + decay=0.5 means an
# article that's 30 days old gets half the score of one published "now".
response = articles.query.near_text(
query="transformer architectures",
limit=5,
boost=Boost.time_decay(
"published",
origin="now",
scale=timedelta(days=30),
curve=Boost.Curve.EXPONENTIAL,
decay=0.5,
weight=0.6,
),
return_properties=["title", "published"],
)

Numeric decay

Like time decay but for numeric (int, number) properties. Use this when "closer to X is better" — prices near a target, distances near a coordinate, ages near a band. Same scale / offset / decay / curve semantics as time decay, with all values expressed as numbers.

scale must be > 0 and decay (if set) must be in (0, 1] — same as time decay.

py docs  API docs
More infoCode snippets in the documentation reflect the latest client library and Weaviate Database version. Check the Release notes for specific versions.

If a snippet doesn't work or you have feedback, please open a GitHub issue.
# Score peaks at a target price and falls off symmetrically. Gauss gives a
# bell-shaped falloff: items within `offset` of $49.99 score 1.0, items at
# $59.99 (one scale away) score `decay`.
response = articles.query.near_text(
query="transformer architectures",
limit=5,
boost=Boost.numeric_decay(
"price",
origin=49.99,
scale=10.0,
curve=Boost.Curve.GAUSSIAN,
decay=0.5,
weight=0.5,
),
return_properties=["title", "price"],
)

Curves

The three decay curves shape how score falls off with distance. At distance == 0 the score is always 1. At distance == scale the score is always exactly decay. Past scale they behave differently:

CurveShapeWhen to use
EXPONENTIAL (default)Heavy tail — score halves geometrically every scale past the origin."Recency matters, but don't aggressively flatten older items to zero."
GAUSSIANBell curve — sharp falloff past scale."Items close to the origin are great, items far away are nearly worthless."
LINEARStraight line — score reaches zero at a finite distance past scale."Predictable falloff with a clear cutoff."

Only these three values are accepted — anything else is rejected at request time.

Blending and weights

A boost must carry at least one and at most 20 conditions. Use Boost.blend(...) to combine multiple conditions into one rescore. Each condition can carry its own weight (default 1.0). The outer weight (default 0.5) controls how much the combined boost affects the final score.

final_score = (1 − weight) · primary_norm + weight · boost_norm
  • weight — the outer blending weight, in [0, 1]. Defaults to 0.5.
  • weight: 0 is a no-op: the boost short-circuits and primary results are returned unchanged.
  • Per-condition weight — a float defaulting to 1.0. Use it to balance multiple boosts ("recency twice as important as popularity").
  • Negative per-condition weightdemotes matching documents. They stay in the result set but rank lower than non-matching ones.
py docs  API docs
More infoCode snippets in the documentation reflect the latest client library and Weaviate Database version. Check the Release notes for specific versions.

If a snippet doesn't work or you have feedback, please open a GitHub issue.
# Combine two soft signals: recency (weight 2) + popularity (weight 1).
# The outer weight=0.4 controls how much the blended rank affects the
# final score; the inner weights are *per-condition* and balance each
# other.
response = articles.query.near_text(
query="transformer architectures",
limit=5,
boost=Boost.blend(
Boost.time_decay("published", origin="now", scale=timedelta(days=30), weight=2.0),
Boost.property("likes", modifier=Boost.Modifier.LOG1P, weight=1.0),
weight=0.4,
depth=200, # rescore the top 200 vector matches
),
return_properties=["title", "likes", "published"],
)

Negative weights demote

A condition with weight: -1.0 (or -2.0, etc.) reverses the effect: documents that match the condition rank below non-matching ones instead of above them. They are not removed. This is useful for deprioritizing — for example, surfacing drafts last without filtering them out.

py docs  API docs
More infoCode snippets in the documentation reflect the latest client library and Weaviate Database version. Check the Release notes for specific versions.

If a snippet doesn't work or you have feedback, please open a GitHub issue.
# A negative per-condition weight pushes matching documents DOWN — they
# stay in the result set but lose ground against everything else. Use
# this to deprioritize drafts without filtering them out entirely.
response = articles.query.bm25(
query="transformer",
limit=5,
boost=Boost.blend(
Boost.filter(Filter.by_property("draft").equal(True), weight=-2.0),
weight=0.5,
),
return_properties=["title", "draft"],
)

# The draft article is still in results, just no longer first.
all_titles = [o.properties["title"] for o in response.objects]
assert any("Draft" in t for t in all_titles)
assert response.objects[0].properties["draft"] is False

Depth and pagination

depth controls the candidate pool. The primary search fetches depth results before the boost rescorer runs. After rescoring, the user's offset and limit are applied.

PropertyValue
Default100
Operator overrideQUERY_BOOST_DEFAULT_DEPTH env var
Hard capQUERY_MAXIMUM_RESULTS (cluster-wide limit)
Lower boundAt least offset + limit — boost always sees enough to fill the page
Accepted range≥ 00 means "use the default"
Raise depth to reorder beyond the top page

Boost can only reorder what the primary search already retrieved. If your boost should reorder past the default top-100 — for example, to pull a popular older article back to page 1 — pass a higher depth on the query.

Higher depth increases the primary search cost (BM25 / vector index work) and per-candidate scoring cost. Set it as tight as your use case allows.

Further resources

  • Rerank — second-stage reranking with an external model.
  • Hybrid search — the BM25 / vector alpha blend.
  • Filters — hard filters (remove non-matching docs).
  • BM25 — keyword search.

Questions and feedback

If you have any questions or feedback, let us know in the user forum.