
A vector database does three plain things: store embeddings, index them, and answer "what's closest?" fast. Here's how that machinery really works (similarity metrics, HNSW and IVF indexes, quantization, filtering) and the many cases where Postgres already does the job.
A deep read: the full picture, with the receipts.
Vendors sell vector databases as mandatory infrastructure for anything with "AI" on the roadmap. They aren't. Strip away the pitch and a vector database does three unglamorous jobs: it stores embeddings, builds an index over them, and answers "what's closest to this?" quickly. That's the whole product. The intelligence you're actually paying for lives in the embedding model that produces the vectors, not in the store that holds them. Before you bolt a managed vector service onto your stack, it's worth understanding exactly what that store does, because your existing database may already do it.
What a vector embedding actually is#
An embedding is what you get when a model reads an object (a sentence, a paragraph, an image, a snippet of code) and emits a fixed-length list of numbers. That list is a coordinate: a single point in a space with hundreds or thousands of dimensions. The model is trained so that things which mean similar things land near each other, regardless of the exact words used. "The invoice is overdue" and "we haven't been paid yet" sit close together; "the invoice is overdue" and "the weather is nice" sit far apart.
Two points are worth nailing down, because they cause most of the confusion:
Dimensionality is a lever, not a fixed cost. Small models emit 384–768 numbers; larger ones go to 1,536 or 3,072 (text-embedding-3-large). More dimensions can capture more nuance but cost more to store and compare. Modern models increasingly support Matryoshka embeddings, where you can truncate a 3,072-dim vector down to 512 or 256 and keep most of the retrieval quality: a cheap, direct way to trade a little accuracy for a lot less storage and latency.
How similarity gets measured#
Once everything is a point in the same space, "similar" becomes "close." Three metrics dominate, and the differences between them are smaller than they look.
The practical takeaway: normalize your vectors and cosine, dot product, and L2 largely converge. "Which metric?" is a much smaller decision than vendors imply.
Why exact search doesn't scale: and what ANN trades away#
The obvious way to find the nearest neighbors is to compare your query vector against every stored vector and keep the top matches. That's a brute-force scan: cost grows with the number of vectors times the number of dimensions. At a few thousand vectors it's instant and you should just do it. At tens of millions, under a latency budget, at real query volume, it falls over.
Approximate Nearest Neighbor (ANN) indexes fix this by giving up a sliver of correctness for a massive speedup. The correctness they give up is measured as recall: the fraction of the true nearest neighbors the index actually returns. Recall@10 of 0.98 means that, on average, the index finds 98 of every 100 true top-10 neighbors. Every ANN index is a recall-versus-speed dial, and both dominant designs let you turn it:
That pairing points at the other big lever: quantization, or compressing the vectors so more of them fit in memory.
In 2026 this is how teams put hundreds of millions of vectors on a single machine without a specialized cluster, and it's a big reason "you need a dedicated database at scale" is less true than it used to be.
The part nobody demos: metadata filtering#
Pure nearest-neighbor search is the easy demo. Real queries almost always carry conditions: nearest neighbors where tenant_id = 42 and status = 'active' and created_at > last_week. Combining a filter with an ANN index is genuinely hard, and it's where a lot of real systems live or die.
There are two naive strategies and both have a failure mode.
This exact problem is why pgvector 0.8 introduced iterative index scans, which keep pulling candidates until enough rows pass the filter, and why every serious vector engine invests heavily in filtered search. If your workload is mostly filtered queries and multi-tenant isolation, this, not raw vector count, is the capability to evaluate.
When you don't need a dedicated vector database#
Most applications that reach for a vector database don't need one yet, and some never will.
pgvector in particular comfortably serves workloads into the millions of vectors. A common rule of thumb puts the point where teams start reaching for a specialized system somewhere around ten million, but that number bends hard with your dimensions, filtering, latency target, and how much RAM you can give the index. Treat it as a smell, not a threshold.
When one actually earns its keep#
Dedicated vector databases (Pinecone, Weaviate, Qdrant, Milvus, and the newer disk-first entrants) are real engineering, and there are workloads where they clearly win:
The pattern to watch for: you are increasingly writing database features, persistence and filtering and replication and backups, around your vector index. That is the signal you have outgrown the bolt-on.
Databases vs. libraries#
It's worth separating two things the word "vector" gets slapped on:
A decision checklist#
Before adding a vector database, price it against these axes: the answer is usually "not yet":
What this sets up#
Getting these mechanics straight is what makes a later comparison of specific services meaningful rather than a vibe check. Once you can reason about index type, recall targets, filtering strategy, quantization, and the operational gap between self-hosted and managed, vendor benchmarks stop being persuasion and start being data you can check. That's the ground the next piece builds on.
Takeaway: A vector database is a focused tool (store, index, and search embeddings) not a prerequisite for having an AI feature. The move from an embedded index or a Postgres extension to a managed service is a real step with real cost, and it's worth taking only when your scale, latency, and filtering demands actually force it. Until then, the boring option is usually the correct one.
Sources
- Malkov & Yashunin, Approximate Nearest Neighbor Search using Hierarchical Navigable Small World graphs (arXiv)arxiv.org
- Johnson et al., Billion-scale similarity search with GPUs / FAISS (arXiv)arxiv.org
- Karpukhin et al., Dense Passage Retrieval for Open-Domain QA (arXiv)arxiv.org
- OpenAI, Vector embeddings (API guide)developers.openai.com



Discussion