Vector Search Simulator: Walk an HNSW Graph One Hop at a Time
Builds a real HNSW index over seeded two-dimensional points and steps through the greedy walk, counting distance computations and measuring recall against a brute-force scan.
The graph found 3 of the 5 genuinely nearest points using 28 distance computations. A brute-force scan is exactly 160 and always gets 5 of 5. Drag efSearch and watch both numbers move together — that trade is the whole reason approximate search exists.
- Points indexed
- 160
- Layers in the graph
- 5
- Entry point
- node 5 at layer 4
- Links per node (M)
- 2
- Edges at layer 0
- 244
- Distance computations descending the upper layers
- 12
- Distance computations at layer 0
- 16
- Distance computations, total
- 28
- Brute-force cost for the same query
- 160
- Work saved against brute force
- 82.5%
- Recall@5
- 3 of 5
What efSearch buys, and what it costs
Vector search is not a lookup. There is no ordering on points in high dimensions and no index that can bracket a range, so every approximate method is a way of avoiding most of the comparisons rather than avoiding a scan entirely. HNSW's answer is a navigable graph: each point links to a handful of near ones, a few points also live in sparse upper layers that act as express lanes, and search is a greedy walk downhill from an entry point. The upper layers get you into the right neighbourhood in a few hops; layer 0 does the careful part.
Drag efSearch up from the left and watch the two numbers move at different rates. At a narrow beam the walk is close to purely greedy: it stops at the first point whose every neighbour is further from the query, even when a better one sits two hops away through a temporarily worse one. That local minimum is the failure the beam exists to escape, and it is what the missing entries in the recall figure are. Widening the beam keeps more candidates alive so the walk can pass through a worse node to reach a better one. On the settings this page opens with, recall reaches its ceiling around efSearch 8 at a cost of six extra distance computations — and everything above that costs linearly more while buying nothing at all. That is the shape of the curve on real indexes too, and finding where your own version of it flattens is the entire tuning exercise.
Two things this page cannot show you and you should not forget. The first is dimensionality: in 2D, nearest neighbours are easy and recall looks generous, while at 768 dimensions distances concentrate, the graph is harder to navigate and the same efSearch buys noticeably less. The second is that recall is measured against exact search, not against being right — a retrieval system with 95% recall can still be a bad retrieval system if the embeddings put the wrong things close together. Recall tells you whether your index is faithful to your embeddings. Whether your embeddings are faithful to your users is a different question, and a harder one.