Skip to content

Lab · Retrieval

What k actually controls

Reciprocal Rank Fusion is two lines in every hybrid retrieval tutorial, and k = 60 is copied into Elastic, Qdrant, Weaviate, and LangChain without comment. Drag it and see what you inherited.

Reciprocal Rank FusionRRF(d) = Σ 1 / (k + rankr(d))

QUERY termination for convenience — notice period

BM25 · lexicalexact terms
  1. 1§4(2)(b) — Termination for convenience
  2. 2§4(2)(c) — Termination for cause
  3. 4§7 — Survival of obligations
  4. 8Notice periods — general obligations
  5. 9Definitions — “Convenience”
  6. 11Schedule 3 — Notice and cure periods
Dense · vectorparaphrase
  1. 6Termination: summary of obligations
  2. 7Schedule 3 — Notice and cure periods
  3. 9Notice periods — general obligations
  4. 12Definitions — “Convenience”
  5. 15§7 — Survival of obligations
  6. 18§4(2)(b) — Termination for convenience
60
1 — trusts confidencetrusts consensus — 200
Fused rankingscore · bm25/dense rank
  1. 1§4(2)(b) — Termination for convenience1/180.02921
  2. 2Notice periods — general obligations8/90.02920
  3. 3Schedule 3 — Notice and cure periods11/70.02901
  4. 4§7 — Survival of obligations4/150.02896
  5. 5Termination: summary of obligations14/60.02867
  6. 6§4(2)(c) — Termination for cause2/200.02863
  7. 7Definitions — “Convenience”9/120.02838
  8. 8Master agreement — recitals17/190.02565

Weight by rank — 1/(k+rank), normalised

rank 1rank 10

Rank 1 : rank 10

1.15×

Top result

§4(2)(b) — Termination for convenience

BM25 is certain (rank 1); the dense retriever barely ranks that clause at all. A duller document that both retrievers merely quite like is waiting to overtake it. The top result flips at k = 63 — three units from the default everyone ships.

How to read it

RRF throws away both retrievers’ scores and keeps only the ordering, then sums 1 / (k + rank) across retrievers. Ranks are the one thing every retriever produces on a comparable scale — rank 1 means the same thing out of BM25 as it does out of FAISS, in a way that 0.83 and 14.2 never will.

k sets how sharply rank position is discounted. At small k, a document ranked first is worth far more than one ranked tenth, so a single confident retriever can carry a result through fusion alone. At large k, the top ten ranks become nearly indistinguishable and what wins instead is agreement between retrievers. The rank 1 : rank 10 readout is that spread, live.

So k = 60 is not a neutral default. It is a strong prior toward consensus — usually right, and exactly wrong when one of your retrievers is categorically better for a query type. The Exact citation scenario is that case: BM25 is not merely better at a statutory reference, it is correct, and consensus-weighting dilutes it.

What to do with it

Sweep k on your own corpus rather than inheriting 60 from a paper written on a different one, and fix retrieval depth per retriever — documents outside a retriever’s top-n contribute nothing, so cutting BM25 at 20 instead of 100 changes fused results in ways that look like a ranking bug rather than a truncation artefact.

The full argument, including where RRF fails and how to evaluate it honestly, is in Reciprocal Rank Fusion in practice. The scenarios here are constructed to isolate one behaviour each — they are illustrations, not benchmark results.