all snippets
2024-11-02postgrespgvectorml

Tuning pgvector HNSW for sub-200ms search

The two knobs that took a 15k-tile visual search from 900ms to under 200ms.

Tuning pgvector HNSW for sub-200ms search

pgvector gives you two useful ANN indexes: IVFFlat and HNSW. For a read-heavy catalog that only re-indexes nightly, HNSW wins.

CREATE INDEX ON products USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

At query time, the knob is ef_search:

SET LOCAL hnsw.ef_search = 40;
SELECT id FROM products
ORDER BY embedding <=> $1
LIMIT 12;

A few notes from actually shipping this:

  • Higher ef_search = better recall, slower query. Sweep it against a labeled set until recall plateaus.
  • m = 16 was enough for 15k rows. For 1M+ push it to m = 32.
  • Warm the index once after boot — the first cold query is always slow.

End result: p95 dropped from ~900ms to ~180ms on a single small Postgres pod.