Tested on pgvector 0.8.7 · PostgreSQL 18.6

Vector search in Postgres, measured.

Install guides, tested SQL and benchmarks we ran ourselves on 500,000 real OpenAI embeddings — so you choose index settings from data, not folklore.

94.7%recall@10 with default HNSW settings
2.9 msmedian query, 100K × 1,536 dims
50%smaller index with halfvec — recall 94.9% vs 94.7% for float32
2,000 Wikipedia articles · OpenAI 3-large

Loading embeddings…

Neighbours are exact top-10 by cosine distance in 1,536 dimensions, computed by pgvector. The 2-D layout (t-SNE) can't preserve every distance, so some true neighbours sit far apart on the map. Colours: 12 k-means clusters.

What is pgvector

Your embeddings, in the database you already run#

pgvector is an open-source PostgreSQL extension that stores embeddings as a column type and finds nearest neighbours with SQL. No second database, no sync jobs: vectors live next to the rows they describe, inside the same transactions, backups and permissions.

  • Four types: vector, halfvec, bit, sparsevec
  • Six distances: L2, cosine, inner product, L1, Hamming, Jaccard
  • Two indexes: HNSW and IVFFlat, plus exact search
  • Free: PostgreSQL License, on Postgres 13+ and every major cloud

Read the reference

The 60-second version — real output from our server:

psqlpsql · semantic search in three statements
demo=# SELECT content, embedding <=> '[1, 1, 0]' AS cosine_distance,
demo-#        1 - (embedding <=> '[1, 1, 0]') AS cosine_similarity
demo-# FROM items ORDER BY embedding <=> '[1, 1, 0]' LIMIT 3;
 content |   cosine_distance    |  cosine_similarity  
---------+----------------------+---------------------
 cat     | 0.004129399346548546 |  0.9958706006534515
 kitten  | 0.010674679844520418 |  0.9893253201554796
 truck   |   0.7712521293869518 | 0.22874787061304824
(3 rows)
sql…then index it
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
Benchmarks · not copied from a vendor

What the settings actually do#

We loaded DBpedia articles embedded with OpenAI text-embedding-3-large into PostgreSQL 18.6, held out 1,000 queries, and measured every index setting against exact search. Some results surprised us.

Recall vs latency: HNSW and IVFFlat on 100K embeddings

Each point is one setting of ef_search (HNSW) or probes (IVFFlat). Up and to the left is better.

  • HNSW (m 16, ef_construction 64)
  • IVFFlat (316 lists)
IndexSettingRecall@10p50 latency
HNSWef_search 100.8151.4 ms
HNSWef_search 200.8971.9 ms
HNSWef_search 400.9472.9 ms
HNSWef_search 640.9703.9 ms
HNSWef_search 1000.9835.3 ms
HNSWef_search 2000.9909.1 ms
HNSWef_search 4000.99516 ms
IVFFlatprobes 10.5501.4 ms
IVFFlatprobes 20.6741.9 ms
IVFFlatprobes 40.7783.1 ms
IVFFlatprobes 80.8575.5 ms
IVFFlatprobes 160.9129.9 ms
IVFFlatprobes 320.95319 ms
IVFFlatprobes 640.97835 ms
Measured on PostgreSQL 18.6 + pgvector 0.8.7, 4 vCPU / 15 GB, DBpedia × OpenAI text-embedding-3-large.Method & raw data
3.6× faster buildsfrom one ALTER TABLE: PostgreSQL launched zero parallel workers for 100K rows of 1,536-dim vectors until we set parallel_workers.Why it happens →
0.4 of 10 rowsreturned on average by a filtered HNSW query matching 1% of rows — until iterative scans are switched on.Filtering guide →
55.0% recallfrom IVFFlat at the default probes = 1. Raising probes to 16 gave 91.2%.IVFFlat guide →
84.1% overlapbetween top-10 neighbours of 3,072-dim embeddings and the same vectors shortened to 1,024 dims.Quantization guide →
Tools

Size it before you build it#

The planner turns your row count, model and recall target into index parameters, memory settings and SQL. The calculator predicts table and index size from pgvector's on-disk format — and shows its error against the indexes we built.

HNSW index size for 100K OpenAI embeddings

Measured on pgvector 0.8.7. Recall@10: vector 0.947, halfvec 0.949 (ef_search 40), binary + re-rank of 160 candidates 0.985.

RepresentationIndex sizeRecall@10
vector781 MB0.947
halfvec391 MB0.949
binary quantized48 MB0.985
Measured on PostgreSQL 18.6 + pgvector 0.8.7, 4 vCPU / 15 GB, DBpedia × OpenAI text-embedding-3-large.Method & raw data
Questions

Short answers, with numbers#

What is pgvector?

pgvector is an open-source PostgreSQL extension that adds vector data types (vector, halfvec, bit, sparsevec), distance operators, and two approximate nearest-neighbour index types, HNSW and IVFFlat. It lets you store embeddings next to your relational data and search them with ordinary SQL — with transactions, joins, backups and replication working as usual.

Is pgvector fast enough for production?

For millions of vectors on one machine, yes. On our modest 4-vCPU test server, an HNSW index over 500,000 OpenAI embeddings (1,536 dimensions) answered single queries in a median of 4.1 ms at recall@10 of 0.931 with default settings. Very large or very high-throughput workloads need more hardware, partitioning or a dedicated system — see the comparison.

Should I use HNSW or IVFFlat?

HNSW for almost everyone: in our benchmark it reached higher recall at lower latency, works on an empty table and handles inserts well. IVFFlat built 9.0× faster and needs far less memory to build, which can matter for very large, rarely-updated datasets — but it must be built after loading data and needs ivfflat.probes tuned.

How many dimensions can pgvector index?

vector columns can be indexed up to 2,000 dimensions; halfvec up to 4,000; binary-quantized bit up to 64,000. For OpenAI's 3,072-dimension text-embedding-3-large, index embedding::halfvec(3072) — in our tests that index reached recall@10 of 0.979 at ef_search = 100.

Does pgvector cost anything?

No. pgvector is released under the PostgreSQL License and runs on any PostgreSQL 13 or newer you control. Managed providers include it at no extra charge; you pay for the database itself.

How we test. Everything here ran on PostgreSQL 18.6 with pgvector 0.8.7 on a 4-vCPU machine. Package versions were read from each source on 2026-10-27. We're independent of the pgvector project and of every vendor mentioned. Method · hello@pgvector.app