HNSW & IVFFlat Indexing
By default, pgvector performs exact nearest-neighbor search (sequential scan), which delivers 100% recall. When your dataset grows beyond tens of thousands of rows, add an approximate nearest-neighbor (ANN) index to trade a small amount of recall for orders-of-magnitude higher query speed.
pgvector includes two built-in index access methods:
- HNSW (Hierarchical Navigable Small World): Multi-layer proximity graph. Higher recall-speed trade-off and no training step required, at the cost of slower build times and higher memory usage.
- IVFFlat (Inverted File with Flat Vectors): K-means clustering over vectors. Faster index builds and smaller index footprint, but requires data to exist before index creation and delivers lower recall per probe than HNSW.
When datasets exceed available RAM (e.g., 10M–1B+ vectors) or HNSW index build times become a bottleneck, install vchord alongside pgvector. vchord’s vchordrq and vchordg index access methods work directly on pgvector’s vector and halfvec columns, compressing vectors with RaBitQ to build up to 100x faster and run efficiently from disk/SSD.
HNSW Indexes
An HNSW index constructs a multilayer navigation graph. Unlike IVFFlat, it has no training phase, so you can create an HNSW index on an empty table before loading data.
Creating an HNSW Index
Create an index matching the distance operator used in your queries:
Supported dimensionality limits for HNSW:
vector: up to 2,000 dimensionshalfvec: up to 4,000 dimensionsbit: up to 64,000 dimensionssparsevec: up to 1,000 non-zero elements
HNSW Build Parameters
m(default16, range2–100): Maximum number of bidirectional links per node per layer. Highermimproves recall on high-intrinsic-dimensionality datasets at the cost of larger index size and longer build times.ef_construction(default64, range4–1000): Size of the dynamic candidate list during graph construction. Must be .
HNSW Query Options
Specify the size of the dynamic candidate list during search (hnsw.ef_search, default 40, range 1–1000). Higher values increase recall at the cost of latency:
Accelerating HNSW Index Builds
HNSW construction speed drops sharply once the graph no longer fits into maintenance_work_mem. Before building an HNSW index on a large table, increase maintenance_work_mem and max_parallel_maintenance_workers:
Always create HNSW indexes after bulk-loading initial data with COPY for significantly faster ingestion. In production, use CREATE INDEX CONCURRENTLY to avoid blocking writes.
IVFFlat Indexes
An IVFFlat index partitions vectors into lists Voronoi cells using k-means clustering, and at query time inspects the closest ivfflat.probes lists.
Because IVFFlat computes k-means centroids during CREATE INDEX, you must load representative data into the table before creating the index.
Creating an IVFFlat Index
Choose lists based on table size:
- Up to 1 million rows:
rows / 1000 - Over 1 million rows:
sqrt(rows)
Supported dimensionality limits for IVFFlat:
vector: up to 2,000 dimensionshalfvec: up to 4,000 dimensionsbit: up to 64,000 dimensions
IVFFlat Query Options
Set the number of lists probed per query (ivfflat.probes, default 1). A good starting point is sqrt(lists):
Index Build Progress & Maintenance
Monitoring Index Build Progress
Query pg_stat_progress_create_index while CREATE INDEX is running:
- HNSW phases:
initializingloading tuples - IVFFlat phases:
initializingperforming k-meansassigning tuplesloading tuples
Vacuuming HNSW Indexes
Vacuuming an HNSW index after heavy deletes can be slow because graph links must be repaired. To speed up DELETE + VACUUM cycles on HNSW tables, rebuild the index concurrently first: