ANN indexes are approximate by design — the knobs trade how often the right answer appears against how fast and how big. Defaults are somebody else's trade-off. This playbook measures recall@k, latency and memory on your data across parameter sets, and publishes numbers the application team can hold you to.
Tier: Advanced · Workflow area: Vector & AI Features · ~45 minutes
HNSW's m and ef_construction, query-time ef_search, DiskANN's graph degree — every one shifts the same three-way trade between recall, latency and resource cost. AI is genuinely useful here as a search-space planner and results interpreter, but the measurements must come from your data and your hardware: recall curves are corpus-specific, and a model's "typical" numbers are folklore. The output is a small published table — the SLA of your search feature.
ORDER BY embedding <=> $1 may meet latency at recall 1.0. Measure that first; no index means no approximation.Build ground truth with exact scans — recall needs a truth to recall. Take 100 representative query vectors (real logged queries, embedded), and compute true top-10 neighbors by brute force:
SET enable_indexscan = off; -- force exact scan for truth
SELECT id FROM products ORDER BY embedding <=> $1 LIMIT 10;
Store results in a ground_truth(query_id, rank, product_id) table. This is the answer key every configuration is graded against.
Have AI design the parameter grid — then prune it to what a day can run. Give the model your constraints and let it plan the sweep:
Corpus: 4.2M vectors, 768 dims, cosine. Hardware: 32 GB RAM,
8 vCPU. p95 latency target: 40 ms with a category filter.
Propose an HNSW parameter grid over m, ef_construction and
ef_search worth benchmarking: no more than 4 build configs
(builds are expensive) and 5 ef_search values per build.
Explain the expected effect of each axis, and predict which
config wins — I will test your prediction.
A sensible grid: builds at m=8/16/24/32 with ef_construction=64–128; ef_search swept 40–400. Making the model predict the winner turns it into a hypothesis you verify — the discipline of this whole track.
Script the benchmark: build, sweep, score. For each build config: create the index (timing it, recording peak maintenance_work_mem usage and final size), then for each ef_search value run the 100 queries and score:
SET hnsw.ef_search = 100;
EXPLAIN (ANALYZE) SELECT id FROM products
ORDER BY embedding <=> $1 LIMIT 10;
SELECT pg_size_pretty(pg_relation_size('idx_products_hnsw'));
Recall@10 per query = |returned ∩ ground truth| / 10; report mean and worst-case. Latency: p50 and p95 over the query set, warm cache. Ask AI to draft the harness script; verify it computes recall against the truth table, not against another approximate run.
Benchmark the filtered case separately — it is a different workload. Repeat the sweep with your real predicate (WHERE category = $2 AND in_stock). Filtered ANN can return fewer than k rows or crater recall at low ef_search; on pgvector 0.8+, iterative scans change the curve. Sample results table:
| config | recall@10 | recall@10 (filtered) | p95 ms | index size | build min |
|---|---|---|---|---|---|
| m=16, efc=64, efs=100 | 0.97 | 0.88 | 18 | 6.1 GB | 42 |
| m=16, efc=64, efs=250 | 0.99 | 0.96 | 33 | 6.1 GB | 42 |
| m=32, efc=128, efs=100 | 0.99 | 0.95 | 24 | 9.8 GB | 97 |
Interpret with AI, decide as a DBA. Paste the results table and ask for the recommendation with reasoning — which config, what breaks first at 10x growth, and what to monitor. Cross-examine it: does its story match the numbers? The decision weighs things the model cannot see: your maintenance window (build minutes), RAM headroom (index size), and how bad a missed result actually is for the product.
Publish the contract and pin the settings. Record the chosen build parameters in the migration, set ef_search explicitly in the application's session or per-query (never rely on a server default someone can change), and publish the table from step 4 with the storage forecast for 10x rows. That document is what "search works" means from now on.
Benchmark on production-scale data, never on production itself — a 4-config build sweep is hours of sustained CPU, memory and I/O pressure. Restore a copy or use a detached replica, and confirm the copy's statistics match production before trusting the numbers.
Approximate indexes make accuracy a tunable — which means accuracy is now your responsibility. Ground truth from exact scans, a measured grid, filtered-case numbers and a published table: that is what owning ANN in production looks like, on any engine.