Open-source PostgreSQL extension for vector similarity search. Two components: (1) the server-side Postgres extension (C, compiled and installed into Postgres), and (2) the Python client package 'pgvector' on PyPI which provides ORM/adapter integrations for psycopg2, psycopg3, asyncpg, SQLAlchemy, Django, SQLModel, and Peewee. The extension name in SQL is 'vector' (CREATE EXTENSION vector), not 'pgvector'. Maintained by Andrew Kane. Current extension version: 0.8.2 (CVE security fix). Python client: 0.4.2.
Install & Compatibility
Where this runs
tested against v0.4.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Vector
✓ from pgvector import Vector
✗ from pgvector.psycopg2 import register_vector
HalfVector
✓ from pgvector import HalfVector
SparseVector
✓ from pgvector import SparseVector
register_vector(conn) must be called after connecting — it registers the custom 'vector' type with psycopg2. Without it, vectors are returned as strings. Extension must be enabled server-side first with CREATE EXTENSION vector.
# Step 1: Enable extension in Postgres (run once per database)
# CREATE EXTENSION IF NOT EXISTS vector;
import psycopg2
from pgvector.psycopg2 import register_vector
import numpy as np
conn = psycopg2.connect("dbname=mydb user=postgres")
register_vector(conn) # REQUIRED: registers the vector type
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS items (id bigserial PRIMARY KEY, embedding vector(3))")
# Insert vectors
cur.execute("INSERT INTO items (embedding) VALUES (%s)", (np.array([1.0, 2.0, 3.0], dtype='float32'),))
conn.commit()
# L2 distance search (<->)
cur.execute("SELECT id FROM items ORDER BY embedding <-> %s LIMIT 5", (np.array([1.0, 1.0, 1.0], dtype='float32'),))
print(cur.fetchall())
cur.close()
conn.close()
Debug
Known issues
breakingCVE-2026-3172: Buffer overflow with parallel HNSW index builds in versions 0.6.0–0.8.1. Can leak sensitive data from other relations or crash the database server. Fixed in 0.8.2.fixUpgrade to pgvector 0.8.2 immediately.
affects: 0.6.0 to 0.8.1
breakingIllegal instruction crashes (SIGILL) when pgvector is compiled with -march=native on one CPU architecture and run on another. Occurs on managed cloud Postgres (Azure Flexible Server, some GCP instances) after upgrading to 0.8.0+.fixReport to your cloud provider. If self-hosting, compile on the same CPU architecture as the runtime. Cannot be worked around from the client side.
affects: 0.8.0+
breakingLangChain's langchain-postgres package requires psycopg3 (package name: psycopg). Connection strings must use postgresql+psycopg:// not postgresql+psycopg2://. Mixing drivers causes driver-not-found errors.fixpip install psycopg[binary]. Use connection string postgresql+psycopg://user:pass@host/db.
affects: all
breakingPostgres 17.0–17.2 causes link error: 'unresolved external symbol float_to_shortest_decimal_bufn' when building pgvector from source.fixUpgrade to Postgres 17.3+.
affects: all source builds against PG 17.0-17.2
gotchaThe SQL extension name is 'vector', not 'pgvector'. CREATE EXTENSION pgvector raises 'extension not found'. This is a consistent source of confusion.fixAlways use: CREATE EXTENSION IF NOT EXISTS vector;
affects: all
gotcharegister_vector(conn) must be called after every new connection. It is not persistent. Failing to call it means vector columns are returned as raw strings, not numpy arrays. No error is raised — silent wrong behavior.fixCall register_vector(conn) immediately after psycopg2.connect(). For connection pools, call it in the connection setup callback.
affects: all (psycopg2)
gotchaHNSW and IVFFlat indexes without ORDER BY + LIMIT do not use the ANN index — Postgres falls back to sequential scan. Queries without LIMIT return exact results but at O(n) cost.fixAlways include ORDER BY embedding <-> $1 LIMIT k in vector search queries. Without LIMIT, the index is not used.
affects: all
gotchaCOSINE distance in pgvector uses the range [0, 2], not [0, 1]. 0 = identical, 2 = opposite. Thresholds from other libraries (which use [0,1]) must be remapped.fixUse pgvector cosine thresholds in [0, 2]. Equivalent: pgvector_threshold = 1 - cosine_similarity.
affects: all
gotchaIVFFlat index must be built AFTER data is loaded. Creating the index on an empty table and then inserting data results in a near-useless index (lists are not representative of the data distribution).fixLoad all or most data first, then run CREATE INDEX. For ongoing ingestion, rebuild or use HNSW which handles incremental inserts better.
affects: all
Audit
Dependencies
psycopg2 or psycopg3 or asyncpgrequiredRequired. pgvector Python package is adapter-only — you must separately install a Postgres driver. psycopg2-binary for sync, psycopg (psycopg3) for async/LangChain.
numpyrequiredRequired when passing vectors as arrays. pgvector accepts Python lists or numpy float32 arrays.