Every few weeks someone asks me which vector database they should use, and they want a single name. I never give one, because the honest answer depends on what you already run, how many vectors you have, and how much operational work you are willing to own. I have shipped systems on several of these, and here is how I actually decide. If the terms embeddings and approximate nearest neighbor are new to you, start with my explainer on vector databases and similarity search first.
Start with the boring answer: pgvector
If you already run Postgres, try pgvector before anything else. It is an extension that adds a vector column type and the index types you need, and it lets you keep your embeddings in the same database as the rest of your data. That last point matters more than people admit. Filtering vector search by a user id, a tenant, or a date range is trivial when the vectors live next to those columns, because it is just a WHERE clause the planner already understands.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documents (
id bigserial PRIMARY KEY,
workspace_id bigint NOT NULL,
body text NOT NULL,
embedding vector(768)
);
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);
SELECT id, body
FROM documents
WHERE workspace_id = 42
ORDER BY embedding <=> '[0.12, -0.03, ...]'
LIMIT 5;
That distance operator does cosine distance, and the HNSW index keeps it fast. For most products with up to a few million vectors, this is all you need, and you avoid running a second system entirely. I have happily left applications on pgvector long past the point where people assumed they would have outgrown it.
When you outgrow Postgres
pgvector has limits. Index builds get heavy as vector counts climb into the tens of millions, memory pressure competes with your transactional workload, and you do not get the specialized knobs a dedicated engine offers. When those start to hurt, it is time to look at a purpose built database. The candidates I reach for are Qdrant, Weaviate, Milvus, and Pinecone.
Qdrant
Qdrant is my default recommendation for a dedicated engine when a team wants to self host. It is written in Rust, the performance is excellent, and its filtered search is genuinely good rather than bolted on. The payload filtering integrates with the vector index so you do not pay the penalty I described earlier where a filter wrecks recall. The API is clean, the docs are honest, and running it in Docker or Kubernetes is straightforward. For most teams leaving pgvector, this is where I point them.
Weaviate
Weaviate leans into being more than a vector store. It has built in modules for generating embeddings, doing hybrid search out of the box, and even orchestrating generative steps. If you want the database to handle more of the pipeline and you like a GraphQL flavored API, it is a strong fit. I find the extra features useful when a team is small and wants fewer moving parts, and less useful when a team already has its own embedding and retrieval code and just wants a fast store.
Milvus
Milvus is the heavy machinery. It is built for very large scale, with a distributed architecture that separates storage and compute, and it supports a wide range of index types. If you are dealing with hundreds of millions or billions of vectors, Milvus is designed for exactly that, and it scales horizontally in ways the others do not match as cleanly. The cost is operational complexity. It is more to run, more to understand, and overkill for a workload that fits comfortably in a single node. Reach for it when the scale genuinely demands it, not before.
Pinecone
Pinecone is the managed, serverless option. You do not run anything, you call an API, and it handles the scaling and operations. For teams that do not want to own infrastructure, that is worth real money, and the developer experience is smooth. The tradeoffs are the usual ones for a managed service: cost at scale, less control, and a dependency on a vendor for a core part of your system. I reach for it when a team is moving fast and infrastructure work is not where they want to spend their limited attention.
How I actually choose
- Already on Postgres, under a few million vectors: pgvector. Do not add a system you do not need.
- Self hosting, want a fast dedicated engine with strong filtering: Qdrant.
- Want the database to own embeddings and hybrid search: Weaviate.
- Hundreds of millions of vectors and a team to run it: Milvus.
- Do not want to run infrastructure at all: Pinecone.
The factors that matter more than the logo
The brand name on the database is the least interesting decision. What actually determines whether you are happy six months later is a shorter list. How well does filtered search perform, because real queries almost always combine similarity with metadata constraints. How painful is reindexing when you change embedding models, which you will. How does cost scale with vector count and query volume. And how much operational burden are you signing up for relative to the team you have.
I have seen far more projects suffer from a poorly tuned index or a bad chunking strategy than from picking the wrong vendor. The database is a component. The system around it, especially the retrieval quality, is where the wins and losses actually happen, which is the subject of building RAG systems with vector databases.
My honest default
Start with pgvector. Prove the product works. Measure your real query patterns and your real vector count. Only move to a dedicated engine when you have evidence that Postgres is the bottleneck, and at that point you will know enough about your workload to choose the right one with confidence. Picking the fancy distributed system on day one is a classic way to spend weeks on operations for a problem you do not yet have.

Leave a Reply