pgvector
pgvector is a PostgreSQL extension: add a vector column to a database you already run, and search with SQL. You do not operate a second vector product. Extension repo: pgvector/pgvector. Postgres itself (install, SQL, indexes) is the PostgreSQL course on this site.
Teams with users and articles already in PG should start here. For a laptop-only RAG spike, use Chroma first.
Enable the extension
Your install must ship pgvector (distro package, Postgres.app, or the pgvector/pgvector Docker image). Then:
Without this, the type and <=> do not exist. If you lack permission, ask an admin to run it once on the target database.
Minimal table and cosine query
Dimensionality must match the embedding model: 1536 for default text-embedding-3-small, often 1024 for bge-m3. Do not change the type later without re-embedding the column.
A real query passes 1536 dimensions; the two-d literal is syntax only. Common operators:
Text embeddings usually use cosine. Skip HNSW on tiny tables; add it around tens of thousands of rows.
Python: psycopg + pgvector
register_vector(conn) lets Python lists / NumPy arrays bind to vector. Skip it and inserts fail with a type error.
On an existing business table, add a column instead of a new database:
Backfill: SELECT id, body FROM articles WHERE embedding IS NULL, embed in batches, UPDATE. Full walkthrough: Practical Examples example 2.
How this fits RAG
One SQL statement can apply WHERE org_id = 42 AND published and ORDER BY embedding <=> :q. That is pgvector’s edge over a pure vector DB: tenancy and time filters live next to similarity. The prompt still needs “answer only from content.”
Next steps
- Qdrant
- PostgreSQL tutorial
- Practical Examples example 2