Both sqlite-vec and pgvector put vector search inside a database you already run, so the decision almost never turns on recall or latency — they both clear the bar for the search itself. It turns on one architectural question: should your vectors ship inside the app, or live behind a connection string? Pick sqlite-vec when your workload is single-writer and read-mostly — a desktop or mobile app, a CLI, an edge function, an agent carrying its own memory — because the whole index is a file with no server to run. Pick pgvector when many clients write at once, when you already operate Postgres, or when you need to JOIN vectors against relational rows in one transaction.
That's the whole answer. The rest is why, and how to tell which one you are.
They solve the same problem from opposite ends#
sqlite-vec is a vector-search extension for SQLite: pure C, no dependencies, and it runs anywhere SQLite runs — Linux, macOS, Windows, a Raspberry Pi, iOS, or the browser via WASM. It stores float, int8, and binary vectors in vec0 virtual tables, does SIMD-accelerated brute-force KNN, and lets you keep metadata alongside the vectors and add distance constraints to a query. The index is part of a file.
pgvector is a vector type and index for PostgreSQL. As of 0.8 it offers HNSW and IVFFlat indexes plus iterative index scans, which keep pulling candidates until a selective WHERE filter is satisfied — the fix for the old problem where filtering after the scan returned too few rows. The index lives in a server that many clients connect to.
Same job — nearest-neighbor search over embeddings — from opposite architectural ends. Embedded vs client-server is the entire decision.
The concurrency line is the real divider#
SQLite's model is one writer at a time, many concurrent readers. That is not a limitation to work around; it's the shape of the problems it's built for:
- One process owns the data. A desktop or mobile app with a per-user database. A CLI. An edge worker. An AI agent that carries its own local memory and ships that memory as a file.
- Reads dominate writes. You embed a corpus occasionally and query it constantly.
The moment your app is a shared service taking writes from many clients at once, SQLite's single writer becomes a bottleneck, and that's precisely the territory pgvector is designed for. If you already run Postgres, the pull is even stronger: your vectors become another column you can JOIN and filter transactionally, with no second datastore and no sync layer to keep consistent.
When sqlite-vec is the right call#
-- one file, zero servers: create a vector table and query it
CREATE VIRTUAL TABLE docs USING vec0(
embedding float[1536],
title text
);
-- k-nearest, with a distance constraint and a metadata filter
SELECT title, distance
FROM docs
WHERE embedding MATCH :query_vec
AND k = 10
AND distance < 0.35;
No connection pool, no network hop, no service to deploy or page you at 3am. The index is a file you can copy, cache, or bundle with the app. Brute-force KNN is exact — the most accurate search there is — and stays fast into the tens to low-hundreds of thousands of vectors on a single process. When you outgrow that, sqlite-vec has an ANN graduation path, but the honest read is: if you need approximate search at large scale with concurrent writers, that's the signal you've outgrown the embedded model entirely.
When pgvector is the right call#
-- vectors as a column, joined against relational data in one query
SELECT d.title, d.embedding <=> :query_vec AS distance
FROM documents d
JOIN accounts a ON a.id = d.account_id
WHERE a.plan = 'pro'
ORDER BY distance
LIMIT 10;
That JOIN is the argument. When the vector lives next to the relational data it's filtered against, one Postgres query does what would otherwise be an application-side merge across two systems. Add concurrent writers and an existing Postgres you already operate, and pgvector isn't just adequate — it's the lower-complexity choice.
The tell#
Ask what your app is, not how fast the search is:
- One process that owns its data, reading far more than it writes → sqlite-vec. Vector search with zero servers and an index that's a file.
- A service many clients hit at once, or data that must live beside relational rows → pgvector. A vector column in a database built for concurrency.
Both are excellent; they're built for different shapes. If your shape is embedded but you want to compare the on-device options head to head, we broke those down in sqlite-vec vs LanceDB vs Chroma for the solo builder. And if you land on a server-side store but aren't sure Postgres is the one, the pgvector vs Pinecone vs Qdrant decision picks up exactly there.



