AnyLearn
All lessons
Computer Scienceintermediate

BM25: How Lexical Relevance Is Actually Computed

Matching finds candidates; scoring orders them, and the ordering is the product. This lesson builds BM25, the default ranking function of Lucene, Elasticsearch and OpenSearch, from its three ingredients: rare terms count more, repeated terms saturate, and long documents get discounted. With the formula, the two tuning knobs, and the saturation curve computed by hand.

Updated · AI-authored, review-gated · how lessons are made

Not signed in: your progress and quiz score won't be saved.
Progress1 / 7

Matching is cheap; ordering is the product

A query for "tomato soup recipe" against a big corpus might match two hundred thousand documents. Nobody reads two hundred thousand results; almost everybody reads ten. The entire commercial value of a search engine is concentrated in which ten float to the top.

That is scoring's job: assign every matching document a number expressing how well it satisfies this query, and sort. The score does not need to be meaningful in absolute terms, and is not, BM25 scores are unbounded and incomparable across queries, it only needs to order documents well.

The modern default, BM25, comes from the probabilistic retrieval tradition developed by Stephen Robertson, Karen Sparck Jones and colleagues, the Okapi BM25 line of work, and became Lucene's default scoring function, which makes it the out-of-the-box ranking of Elasticsearch, OpenSearch and Solr.

Key idea: BM25 is three intuitions with algebra attached: terms that are rare in the corpus carry more information; a term appearing repeatedly in a document matters more, but with sharply diminishing returns; and matches in long documents count for less than matches in short ones. Learn the three and the formula assembles itself.

Full lesson text

All 7 steps on one page, for reading, reference, and search.

Show

1. Matching is cheap; ordering is the product

A query for "tomato soup recipe" against a big corpus might match two hundred thousand documents. Nobody reads two hundred thousand results; almost everybody reads ten. The entire commercial value of a search engine is concentrated in which ten float to the top.

That is scoring's job: assign every matching document a number expressing how well it satisfies this query, and sort. The score does not need to be meaningful in absolute terms, and is not, BM25 scores are unbounded and incomparable across queries, it only needs to order documents well.

The modern default, BM25, comes from the probabilistic retrieval tradition developed by Stephen Robertson, Karen Sparck Jones and colleagues, the Okapi BM25 line of work, and became Lucene's default scoring function, which makes it the out-of-the-box ranking of Elasticsearch, OpenSearch and Solr.

Key idea: BM25 is three intuitions with algebra attached: terms that are rare in the corpus carry more information; a term appearing repeatedly in a document matters more, but with sharply diminishing returns; and matches in long documents count for less than matches in short ones. Learn the three and the formula assembles itself.

2. Ingredient one: rarity, measured as IDF

In the query "the tomato harvest", the term "the" matches essentially every document; "tomato" matches a slice; "harvest" perhaps a sliver. A match on "harvest" is therefore evidence; a match on "the" is noise. Inverse document frequency turns that into a number: the fewer documents a term appears in, the larger its weight.

The BM25 variant, with N total documents and n(t) containing term t:

IDF(t)=ln ⁣(Nn(t)+0.5n(t)+0.5+1)\mathrm{IDF}(t) = \ln\!\left( \frac{N - n(t) + 0.5}{n(t) + 0.5} + 1 \right)

The shape is what matters: a term in half the corpus gets a weight near zero, a term in one document in a million gets a large one, and the curve moves smoothly between. The 0.5 terms smooth the edge cases, and the plus one inside the logarithm, Lucene's variant, keeps the value positive even for absurdly common terms.

Two practical consequences. IDF is why engines can often skip dedicated stop word lists: "the" earns a near-zero weight automatically, no configuration needed. And IDF is corpus-relative: "tomato" is a strong term in a general news corpus and a weak one inside a recipe database, so the same query ranks differently against different collections, exactly as it should.

3. Ingredient two: repetition, with a ceiling

A document mentioning "tomato" eight times is probably more about tomatoes than one mentioning it once. Early scoring, raw TF-IDF, took that linearly: eight mentions, eight times the credit. Linearity turned out to be both wrong and exploitable, wrong because the ninth mention of a word adds almost no new evidence about the document's topic, exploitable because stuffing a page with a keyword bought rank.

BM25's answer is saturation. The term frequency contribution passes through f times k1 plus 1, over f plus k1, which climbs steeply at first and flattens toward a ceiling.

BM25 term contribution vs occurrences, k1 = 1.2
contribution00.511.522.5124816
Source: computed: f(k1+1)/(f+k1) with k1 = 1.2, length normalisation off
Predict first

With k1 at 1.2, a document mentions the query term 16 times instead of once. How much more scoring credit does it earn?

4. Ingredient three: length, normalised

The third correction handles an unfairness: a 40-word product title that mentions "tomato" once is intensely about tomatoes; a 4,000-word article that mentions it once, in passing, is not. Raw counting treats them identically.

BM25 discounts term frequency by how the document's length compares to the corpus average. The document's frequency denominator is inflated for long documents and deflated for short ones, scaled by the ratio of document length to average document length, so a match in a short, focused document outscores the same match diluted across a long one.

The strength of the discount is the second tuning knob, b, running from 0, no length normalisation at all, to 1, full proportional normalisation. The default 0.75 is a compromise that has survived decades of empirical testing.

When would you move it? Fields with meaningful, deliberate length differences want lower b: a title field, where every word was chosen, is often scored with b near zero, while body text keeps the default. Corpora where length just means thoroughness, encyclopaedia articles, may also want gentler discounting: a long comprehensive article is not diluted, it is complete. As with analysis, per-field configuration is the norm, not the exception.

5. The assembled formula

Put the three ingredients together, summed over the query's terms:

score(D,Q)=tQIDF(t)f(t,D)(k1+1)f(t,D)+k1(1b+bDavgdl)\mathrm{score}(D, Q) = \sum_{t \in Q} \mathrm{IDF}(t) \cdot \frac{f(t, D) \cdot (k_1 + 1)}{f(t, D) + k_1 \cdot \left(1 - b + b \cdot \frac{|D|}{\mathrm{avgdl}}\right)}

Reading it aloud: for each query term, take its rarity weight, multiply by its saturated within-document frequency, where the saturation denominator has been stretched or shrunk by the document's relative length, and add the contributions up.

SymbolMeaningTypical value
f(t, D)Occurrences of term t in document Dfrom the postings
k1Saturation speed: how fast repetition stops paying1.2
bLength normalisation strength, 0 to 10.75
avgdlAverage document length in the corpusmeasured

Notice what the formula does not know: word order, term proximity, which field matched, document freshness, popularity, whether anyone ever clicked this result. BM25 is a per-term, bag-of-words calculation. Everything on that missing list is added around BM25, phrase and proximity features, per-field scoring with boosts, freshness signals, and that layering is precisely the subject of the rest of the course.

6. Scoring a real query, by hand

A worked miniature makes the moving parts concrete. Corpus: 1,000 recipe documents, average length 100 terms. Query: "tomato bisque". Term statistics: "tomato" appears in 200 documents, "bisque" in 5. Constants at defaults, k1 1.2, b 0.75.

IDF: tomato gets ln((1000 - 200 + 0.5) / (200 + 0.5) + 1), about 1.61. Bisque gets ln((1000 - 5 + 0.5) / (5 + 0.5) + 1), about 5.20. The rare term is worth three times the common one before anyone counts occurrences.

Document A, 50 terms long, mentions tomato twice, bisque once. Its length factor is 1 - 0.75 + 0.75 times 50 over 100, which is 0.625. Tomato's contribution: 1.61 times (2 times 2.2) over (2 plus 1.2 times 0.625), about 2.57. Bisque's: 5.20 times 2.2 over (1 plus 0.75), about 6.53. Total: 9.10.

Document B, 200 terms, mentions tomato six times, no bisque. Length factor 1.75. Contribution: 1.61 times 13.2 over (6 plus 2.1), about 2.62. Total: 2.62.

Document A wins by a wide margin, and the arithmetic shows why in one sentence: one occurrence of the rare, on-topic term in a short document beat six occurrences of the common one in a long document. That single sentence is BM25's whole personality.

7. Where BM25 stops

Knowing a tool's edges is knowing the tool, and BM25's edges are sharp and well-mapped.

  • Vocabulary mismatch. BM25 scores term overlap. "Notebook" and "laptop" share no terms, so a query for one cannot rank documents about the other, however perfect the match in meaning. Synonym lists patch the known cases; the long tail of paraphrase stays broken. This is the gap embeddings exist to close, next lesson.
  • No understanding of intent. The query "jaguar speed" scores identically whether the user means the cat or the car; nothing in term statistics can disambiguate it.
  • Bag of words. "Dog bites man" and "man bites dog" score identically. Proximity and phrase machinery must be layered on where order matters.
  • No quality signal. An authoritative page and a spam page with the same term statistics tie. Popularity, freshness, and behavioural signals live outside the formula.

Against these stands what BM25 does supremely well: exact vocabulary, identifiers, names, rare terms, no training data required, explainable scores you can decompose term by term, millisecond-cheap at any scale, and robust across domains with two knobs of tuning. Production search does not choose between BM25 and the modern alternatives; it runs BM25 as the reliable backbone and adds what the backbone cannot see, which is exactly where this course goes next.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. Why does IDF weighting largely eliminate the need for stop word lists?
    • Stop words are removed by the tokenizer first
    • Terms appearing in most documents automatically earn near-zero weight, so their matches barely move scores
    • IDF deletes common terms from the postings lists
    • Stop words are capped at one occurrence per document
  2. With k1 = 1.2, roughly how much more does 16 occurrences of a term contribute than 1 occurrence?
    • About 16 times
    • About 8 times
    • About 2 times, because the contribution saturates
    • Exactly k1 times
  3. What does the parameter b control?
    • The strength of document length normalisation, from none at 0 to full at 1
    • The number of query terms considered
    • The saturation ceiling for term frequency
    • The base of the IDF logarithm
  4. In the worked example, why did document A (tomato twice, bisque once, 50 terms) beat document B (tomato six times, 200 terms)?
    • Because document A was indexed more recently
    • Because phrase matching rewarded the adjacent terms
    • Because six occurrences exceed the saturation limit and score zero
    • Because one match on the rare term in a short document outweighed many matches on the common term in a long one
  5. Which query failure is fundamentally beyond BM25's reach, rather than a tuning issue?
    • A rare term being weighted too heavily
    • Ranking documents about laptops for the query notebook, when the documents never use that word
    • Long documents scoring too low
    • A term appearing many times earning too little credit

Related lessons

Computer Science
intermediate

Measuring Relevance: Judgments, NDCG, and the Click Trap

Search quality arguments end when there is a number, and begin again over whether the number is honest. This lesson builds offline evaluation from its atoms: a judgment set, precision and recall at k, MRR for known-item queries, and NDCG computed by hand for graded relevance. Then the online half: clicks, position bias, and why the top result gets clicked even when it is wrong.

7 steps·~11 min
Computer Science
intermediate

The Inverted Index, and Why Analysis Decides Everything

Search does not scan documents; it looks up precomputed answers. This lesson builds the inverted index from first principles, then covers the pipeline that feeds it: tokenization, normalisation, stemming and synonyms, and why an analysis mistake made at index time cannot be fixed at query time. Includes the classic failure where a product SKU becomes unfindable.

7 steps·~11 min
Computer Science
intermediate

Lexical Meets Vector: Hybrid Search and Rank Fusion

Vector search did not replace keyword search, because the two fail in opposite places: BM25 cannot see that laptop and notebook mean the same thing, and embeddings cannot see that SKU-4471-B is not approximately anything. This lesson maps the two failure surfaces, then builds the production answer: run both retrievers and fuse the rankings, with reciprocal rank fusion done by hand.

7 steps·~11 min
Business
intermediate

Why one page beats another

Thousands of pages match your query; the engine picks ten and orders them. Learn the four questions ranking answers, why links became a proxy for trust, what PageRank actually measured, how the query itself is interpreted before anything is scored, and why chasing individual ranking factors is the wrong mental model.

8 steps·~12 min