SysDesignPrep.com
Interactive concepts

Approximate nearest neighbour search with an IVF index: interactive recall vs speed

Semantic search, recommendations and retrieval for LLMs all turn items into embedding vectors and look for the vectors nearest to a query. Comparing the query with every vector is exact but slow at millions of items, so vector databases use approximate nearest neighbour (ANN) indexes that look at a small part of the data and accept missing a few true neighbours. The IVF index, an inverted file of clusters, is the simplest of them.

The playground clusters 600 vectors, drawn in two dimensions, and searches for the 10 nearest to a query. Click to move the query, and change how many lists the index has and how many it probes.

ListsProbe

600 vectors in 16 lists, about 38 each. The query is compared with the 16 centroids, then with every vector in the nearest list: 64 comparisons instead of 600. It found all 10 true nearest neighbours. Averaged over 300 queries near real vectors, this setting finds 86% of the true neighbours with 60 comparisons.

This query10 of 10true neighbours found
Compared64vectors and centroids, of 600
Average recall86%over 300 queries, 60 comparisons each

Click the plot to move the query.

in a probed listtrue neighbour, foundtrue neighbour, missedreturned insteadcentroid

How an IVF index works

Building the index runs k-means to find centroids and files every vector in the list of its nearest centroid. A query is compared with the centroids, then with the vectors in the nprobe nearest lists only. With 16 lists and one probe, a query in the middle of a cluster finds all 10 true neighbours after 64 comparisons instead of 600. A query near a border is the weak spot: its nearest neighbours lie partly in the next cell, and probing one list finds just 1 of 10. Probing 2 lists recovers all 10 for 77 comparisons.

  • More probes raise recall and cost, roughly in proportion.
  • More lists make each list smaller, so each probe is cheaper, but more queries sit near a border; pair more lists with more probes.
  • Starting points from pgvector’s documentation: rows / 1,000 lists up to a million rows and the square root of the rows beyond that, with probes around the square root of the lists, then measure.

At scale the savings are large: 100 million vectors in 10,000 lists, probing 100, compares a query with 10,000 centroids and about a million vectors, 1% of the data.

IVF, HNSW and quantization

HNSW, a layered graph in which each vector links to its near neighbours, usually reaches higher recall at lower latency and handles inserts without retraining, at the cost of more memory and slower builds; it is the default in many vector databases. IVF builds fast and stays compact, and combined with product quantization, which compresses each vector to a few bytes, IVF-PQ is how billions of vectors fit in memory. Whatever the index, measure recall by comparing its results with exact search on a sample of real queries.

An IVF index in PostgreSQL with pgvector

CREATE EXTENSION vector;
CREATE TABLE docs (id bigserial PRIMARY KEY, body text, embedding vector(1536));

-- an IVF index: k-means runs when it is built, so build it after loading data
CREATE INDEX ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists = 1000);

SET ivfflat.probes = 32;          -- more probes: higher recall, slower queries
SELECT id, body FROM docs ORDER BY embedding <=> $1 LIMIT 10;

In a system design interview

When a design retrieves by meaning, say how and at what accuracy: “Documents are chunked and embedded, and the 20 million chunk vectors live in an IVF index with about 4,500 lists. We probe 64, which gave 95% recall@10 against exact search on a sample of logged queries, at about 20 ms. Filters such as tenant are applied inside the index scan, not after, so a small tenant still gets 10 results.” Expect the follow-ups: how the index is rebuilt as data drifts, HNSW versus IVF, and combining vector search with keyword search.

Read the guide to ANN indexes or vector search and RAG, compare the inverted index behind keyword search, or watch a strong candidate design an LLM inference service.

Questions people ask

What is approximate nearest neighbour search?

Finding the vectors closest to a query without comparing it with every vector. ANN indexes such as IVF and HNSW examine a small, promising part of the data and return most of the true nearest neighbours, trading a little recall for searches that are orders of magnitude faster than an exact scan.

How does an IVF index work?

At build time, k-means groups the vectors into clusters, and each vector is stored in the list of its nearest centroid. At query time, the query is compared with all centroids, and only the vectors in the few nearest lists, the probes, are compared with the query to pick the top results.

What is nprobe?

The number of lists an IVF index searches for each query. One probe is fastest but misses neighbours that sit in an adjacent cluster when the query is near a border; more probes raise recall at a roughly proportional cost. In pgvector it is the ivfflat.probes setting.

How many lists should an IVF index have?

A common starting point, from pgvector’s guidance, is rows divided by 1,000 for up to a million rows and the square root of the number of rows beyond that, with probes around the square root of the number of lists. Then measure recall and latency on real queries and adjust.

What is recall in vector search?

The share of the true nearest neighbours, found by an exact search, that the approximate index returns. Recall@10 of 95% means that on average 9.5 of the true top 10 appear in the index’s top 10. It is measured by running exact and approximate search on a sample of queries.

IVF vs HNSW: which should I use?

HNSW usually gives better recall at low latency and supports incremental inserts, but uses more memory and builds slowly. IVF builds quickly, uses less memory, and combined with product quantization scales to billions of vectors, but needs data to train its clusters and can drift as data changes.

Why does filtering make vector search harder?

If filters are applied after the approximate search, a selective filter can remove most of the top results, leaving too few. Good systems apply filters during the index scan or partition the index by the filter key, such as tenant, so filtered queries still return enough results.