Once a vector table grows past a few hundred thousand rows, a flat scan that compares a query against every stored embedding stops being viable — and this is exactly the point where an enterprise Postgres deployment on pgvector has to pick an index type. The two production options are HNSW and IVFFlat, and they trade off build cost against query speed in opposite directions.
How the Two Index Types Actually Differ
IVFFlat divides the vector space into a fixed number of clusters ("lists") using k-means at build time, then only searches the handful of lists nearest to the query vector. Per pgvector's own documentation, the create syntax is:
-- lists: pgvector recommends rows/1000 for up to ~1M rows,
-- or sqrt(rows) once you're past that
CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100);
HNSW instead builds a multi-layer navigable graph, where each vector is a node connected to its approximate nearest neighbors at several levels of granularity. There's no training/clustering step — the graph grows incrementally as rows are inserted:
-- m: max connections per graph layer (default 16)
-- ef_construction: candidate list size while building (default 64)
CREATE INDEX ON items USING hnsw (embedding vector_l2_ops) WITH (m = 16, ef_construction = 64);
The Actual Trade-off
pgvector's own docs summarize it plainly: HNSW "has better query performance than IVFFlat (in terms of speed-recall tradeoff), but has slower build times and uses more memory." IVFFlat is the inverse — cheaper and faster to build, lighter on RAM, but lower recall for the same query time, and its clusters need periodic rebuilding as the table grows if you want to keep recall stable. Independent benchmarking from cloud vector-database vendors has found HNSW queries running roughly 3x faster than IVFFlat at comparable recall, while IVFFlat index builds can finish an order of magnitude faster — differences large enough to matter when you're indexing tens of millions of rows on a real budget, not just a benchmark toy set.
| Factor | IVFFlat | HNSW |
|---|---|---|
| Build time / memory | Faster, lower memory (no graph structure) | Slower, higher memory (stores the full graph) |
| Query speed / recall | Lower recall at the same latency | Better speed-recall trade-off |
| Maintenance | Needs periodic rebuild as data grows | Grows incrementally with inserts |
For most production RAG or semantic-search workloads where the table already has data before the index exists and query latency matters more than the one-time build cost, HNSW is the more common default in 2026 precisely because it needs less retuning as the table grows. IVFFlat still earns its place on workloads where you can tolerate lower recall in exchange for a much cheaper, faster index build — for example, a nightly-rebuilt analytics table where the index is thrown away and recreated on every load anyway.
Practical Challenge
On a Postgres table with pgvector installed, build both an IVFFlat and an HNSW index on the same embedding column, then compare EXPLAIN ANALYZE output for the same query against each — note the difference in planning time versus execution time.
Concept Check
Sources & Further Reading
- pgvector GitHub README — the authoritative source for HNSW/IVFFlat build parameters, creation syntax, and the project's own speed/memory/build-time guidance quoted above.
- pgvector performance: Benchmark results (Instaclustr) — independent benchmark numbers on HNSW vs. IVFFlat query speed and build-time differences.
AI