Choosing an approximate-nearest-neighbor index is, today, a research project per dataset.

There's HNSW. There's IVF, with optional product quantization. There's ScaNN, OPQ, Vamana, PCA-then-cosine, raw scalar quantization, and a half-dozen variations on each. Every one of them has knobs, every one of them has a paper claiming superiority on some benchmark, and every one of them has a different recall and latency profile depending on the shape of the data you point it at.

That's a lot to expect a customer to know.

So we don't.

What we measure

What auto-optimize measures: every viable index strategy is tested on a sample of your vectors across three dimensions. Recall @ k (true nearest neighbors found), p95 query latency (the slow end of typical response time), and build cost (build time and memory needed to construct the index).

When you create a collection, we sample your vectors and run every viable indexing strategy against that sample. For each strategy and each parameter set, we measure three things:

These get measured on a sample of your vectors. Not GloVe, not SIFT-1M, not any benchmark dataset. Yours.

The Pareto frontier

The output is a scatter plot: recall on one axis, p95 latency on the other, one dot per (strategy, parameter set) configuration tested. Some dots are obviously bad: low recall and slow. Some are pleasantly fast but inaccurate. A few sit on the Pareto frontier: the set of configurations where you can't make recall better without making latency worse, and vice versa.

The Pareto frontier illustrated: each dot is one (strategy, parameter set) configuration plotted by recall and p95 latency. The chosen winner sits highest-and-leftmost on the frontier, where you can't improve recall without worse latency.

What that looks like in practice on a real run:

Auto-optimization dashboard showing 108 of 378 tests run, current best is PCA index 6659 at 100% recall and 87% faster than baseline. Scatter plot of recall vs p95 latency.

In the run above, 108 of 378 configurations have finished. PCA ID 6659 is the current leader: 100% recall, 87% faster than the brute-force baseline. HNSW ID 1919 is up next. The frontier moves as more results come in. When the run finishes, the chosen winner is whichever point sits highest-and-leftmost on the final frontier.

The strategies we test

Eleven candidates, today:

Eleven index strategies grouped by family: exact baseline (Brute-force), graph indexes (HNSW, Vamana, PCA), inverted-file family (IVF-Flat, IVF-PQ, PQ), compression and projection (OPQ, SQ), learned and hashing (ScaNN, LSH).

What auto-optimize does with the result

What happens after the tests: the top performer (HNSW with specific parameter set) becomes the winner and serves all queries. Loser configurations are not retained. Re-runs happen on explicit reindex; indexes are not quietly swapped underneath you. Override available for tighter latency budgets, hard memory ceilings, or benchmark reproducibility.

The winner serves your queries. The losers don't get retained: no shadow indexes burning storage, no toggle-it-on-later complexity, no quiet drift between what you thought was running and what's running.

You can browse the frontier in your collection's view: every dot, the live one highlighted, the runner-up gap visible. While optimization is still running, your queries use the best index found so far — we promote a new one whenever we discover a meaningful improvement, so you don't sit on the brute-force baseline for several days waiting for the full sweep. Once optimization completes, the winner is locked: re-runs happen only on explicit reindex, never silent swaps. Index usage is free until the full sweep reaches 100%.

PCA was once a frequent auto-pick. Then a customer pushed in vectors where PCA was throwing away the high-magnitude components and recall fell off a cliff. We don't want that bug to be silent, which is part of the reason we keep brute-force as ground truth and measure recall against it on every run. (See the build-log entry "PCA forgot the magnitudes" for the gory detail.)

When to override

The auto-pick is the right starting point for almost every collection. The real reasons to override are narrow:

Overrides are explicit in the SDK and visible in the collection view. Anyone looking at your collection can tell what's running and why.

Further reading

You don't need to read these papers to use Vector Panda. If you'd like to:

The shape of the field is straightforward once you have the vocabulary. We picked these eleven because they cover the design space well. We're open to adding others if there's a real reason to.