insideout Get Pro
Compare

Compare

Vector search vs keyword search

Embeddings find meaning, keywords find exact terms, so run both.

The short answer

Vector search compares embeddings, so it finds passages that mean the same thing in different words. Keyword search (BM25) scores passages by the words they share with the query, with rare words counting more, so it finds exact codes, names and terms. Their misses fall in different places, which is why many search systems run both and merge the results.

Vector search

Use it when

  • People ask in their own words.
  • Questions rarely use your documents' exact wording.
  • You also want to group or label text by topic.
What it costs
An embedding model, every passage embedded once and stored, and an approximate index at scale. Ten million vectors of 1,536 numbers take about 61 GB as 4-byte floats.
Watch out
Exact strings blur: E-4012 and E-4021, or 5 mg and 500 mg, look almost the same to an embedding. Changing the model means embedding everything again.

Keyword search (BM25)

Use it when

  • Queries hold codes, names or IDs.
  • Users search with the same words your documents use.
  • You want search running today, with no model and no GPU.
What it costs
Cheap: an index of words on ordinary machines, with millisecond lookups over millions of passages. Most of the tuning is in how text is split into words.
Watch out
It matches words, so a question about getting "money back" misses a passage that only says "refund".

At a glance

QuestionVector searchKeyword search (BM25)
What it comparesEmbeddings: lists of numbers that sit close when meanings are closeThe words a query and a passage share, rare words weighted more
Strong atParaphrases and loosely worded questionsExact codes, names and rare terms
Weak atExact identifiers, amounts and negationSynonyms and different wording
Needs a modelYes, the same one for passages and queriesNo
IndexVectors, with an approximate index such as HNSW at scaleAn inverted index of words
What you tuneThe embedding model, chunk size and the index's recallHow text is split into words, then k1 and b

How to choose

  1. Collect 100 to 200 real queries and mark the passages that answer each one.
  2. Run BM25 first: it takes an afternoon and gives you a baseline to beat.
  3. Add vector search and compare recall at the number of passages your model will actually read.
  4. If each one finds passages the other misses, merge them with reciprocal rank fusion and measure again.
  5. Add a reranker only once the right passages are reaching the top 50.

When you need both

Hybrid search runs both on every query. The two scores don't share a scale (BM25 has no fixed top, while cosine similarity sits between −1 and 1), so adding them gives you BM25 in disguise. Merge by rank instead: reciprocal rank fusion gives each passage 1 ÷ (60 + rank) from every list it appears in and sorts by the total, so passages both retrievers found rise to the top. A common setup takes the top 50 from each, fuses them, then reranks the best few.

Learn it properly

Questions

Is vector search better than BM25?

Not on every job. On BEIR, a benchmark of 18 search datasets from different fields, plain BM25 beat several neural retrievers that hadn't been trained on those fields. Embeddings win on paraphrases, BM25 on exact terms, and the two together usually beat either one.

What is hybrid search?

Running a keyword retriever and a vector retriever on the same query, then merging their two ranked lists into one. Reciprocal rank fusion is the usual merge, because it uses only positions, so the two scoring scales never have to agree.

Why can't I just add the two scores?

BM25 scores run into the tens and change with every query and collection, while cosine similarity stays between −1 and 1. Added together, BM25 decides almost the whole order. First place means the same thing in both lists, which is why fusion works on ranks.

Do I need a vector database?

Not at first. A few hundred thousand chunks fit in one machine's memory with exact search or a library index. Reach for a separate service when you need its filtering, replicas or live updates.