Vector Databases Explained: Pinecone, Weaviate, and Beyond
A deep dive into vector databases and their role in AI applications. Compare popular options and learn when to use each for semantic search and recommendation systems.
Vector databases went from niche to unavoidable in about two years, and a lot of teams adopted one before working out whether they needed it. This is an attempt at the honest version: how the technology works, when a dedicated database earns its place, and how the main options actually differ.
What a vector database is for
An embedding model turns text, images or audio into a list of numbers - a vector - positioned so that similar meanings land near each other. "How do I reset my password" and "I forgot my login" end up close together despite sharing almost no words.
The retrieval problem is then: given a query vector, find the nearest ones in a collection. Comparing against every stored vector is exact and unusably slow past a few hundred thousand records. A vector database's actual job is doing that search approximately, in milliseconds, with an accuracy you can tune.
You are trading exactness for speed. The important question is not whether the trade happens, but whether you can see and control where it lands.
The index types you will meet
A layered graph, searched by descending from a coarse top layer to a dense bottom one. It is the default nearly everywhere because it gives excellent recall at low latency.
The costs are real and worth knowing before you commit: the index lives in memory, so RAM scales with your vector count, and building it is slower than the alternatives. For most workloads under a few tens of millions of vectors, it is still the right answer.
Clusters the vectors, then searches only the nearest few clusters. Lower memory and faster to build than HNSW, with somewhat lower recall at equivalent speed. It needs a training step on representative data, which makes it a poorer fit where the collection changes constantly.
Not an index but a compression layer, usually combined with one. Product quantisation can cut memory dramatically at some accuracy cost; binary quantisation is more aggressive again and increasingly viable because newer embedding models tolerate it well.
The pattern that works in production is to search a quantised index for a generous candidate set, then rerank those candidates against full-precision vectors. You get most of the memory saving and most of the accuracy.
Do you need a dedicated vector database at all?
This is the question worth asking before the comparison, because for a large share of projects the answer is no.
pgvector - the PostgreSQL extension - handles vector search inside a database you probably already run. It supports HNSW, it participates in ordinary SQL, and crucially it lets you filter and join against your relational data in one query rather than coordinating two systems.
- You are below roughly a few million vectors. This covers most document search, support knowledge bases and internal RAG systems.
- Your queries filter heavily on relational attributes - tenant, permission, date, category. Doing this in SQL is simpler and more correct than replicating the filter in a second store.
- You want one system to back up, monitor, secure and reason about. This is worth more than it sounds.
- You are in the tens of millions of vectors or beyond, where purpose-built indexing and memory management genuinely diverge from a general database.
- Query volume is high and latency-sensitive - vector search competing with transactional load on the same PostgreSQL instance is a bad neighbour problem.
- You need features PostgreSQL does not have: managed hybrid search, built-in multi-tenancy, or a serverless model where you do not manage capacity.
Starting on pgvector and migrating later is a reasonable plan and a common one. The embeddings are portable; it is the ingestion and query code that has to be rewritten, and keeping that behind a thin interface makes the eventual move a day rather than a project.
How the main options differ
Deliberately qualitative. Pricing and limits move too quickly for a written comparison to stay accurate, so check the current figures before deciding - what follows is the shape of each option rather than its price list.
| Option | Model | Strongest when | Watch out for |
|---|---|---|---|
| Pinecone | Fully managed, serverless | You want zero operational burden and predictable performance without tuning | Least control over index internals; a managed dependency in your critical path |
| Weaviate | Open source, managed option | You want built-in hybrid search and a schema with real object structure | More concepts to learn; self-hosting is genuine operational work |
| Qdrant | Open source, managed option | Filtering matters and you want strong performance from a self-hosted deployment | Smaller ecosystem than the largest players |
| Milvus | Open source, managed as Zilliz | Very large collections and you need index-level control | The most operationally demanding of these to self-host |
| pgvector | PostgreSQL extension | Moderate scale with heavy relational filtering | Vector search shares resources with your transactional workload |
| OpenSearch / Elasticsearch | Search engine with vector support | You already run it and need lexical and vector search together | Vector performance trails purpose-built stores at scale |
The differences that actually decide the choice, in our experience, are rarely raw benchmark numbers. They are filtering behaviour, hybrid search support and the operational model.
Filtered search: the detail that catches people
Almost every real query is filtered. Search this tenant's documents. Search what this user may read. Search the last ninety days.
How a store combines the filter with the vector search matters enormously, and there are three approaches:
- Pre-filtering - restrict the candidate set, then search within it. Correct, but it can defeat the index structure and fall back toward a scan when the filter is narrow.
- Post-filtering - search first, then discard non-matching results. Fast, and it silently returns fewer results than requested when the filter is selective. This is the one that produces mystifying bugs.
- Filtered graph traversal - the filter is applied during the search itself. The best outcome, and it is where implementations differ most.
Test this with your own selective filters before committing. A store that looks excellent on unfiltered benchmarks can behave very differently when every query is scoped to one tenant out of ten thousand.
Hybrid search is not optional
Pure vector search is reliably weak on exact terms: product codes, error numbers, proper nouns, version strings. A user searching for error E4021 wants the passage containing E4021, and an embedding model considers E4022 to be extremely similar.
Combining BM25 keyword scoring with vector similarity and fusing the results - typically with reciprocal rank fusion - is the largest single quality improvement available to most retrieval systems. Some stores provide it natively; with others you run two searches and fuse in application code, which is more work but entirely workable.
The embedding model matters more than the store
Teams spend weeks comparing databases and an afternoon choosing an embedding model. That is backwards. The store decides how fast you find the nearest vectors; the model decides whether being near means being relevant.
Three considerations, in order of impact:
- Domain fit. General-purpose models handle general prose well and are often noticeably weaker on dense technical, legal or medical material. Evaluate on your own documents - public benchmarks are not measuring your corpus.
- Dimensions. This is your memory bill. Many current models are trained so the vector can be truncated with modest accuracy loss, which is a real lever and one worth measuring rather than assuming.
- Where it runs. A hosted embedding API means every indexed document leaves your network. If that is a problem for your data, it is far cheaper to decide before the first ingestion run than after.
Store the model name and version alongside every vector. When you migrate - and you will - that record is what lets you re-embed correctly instead of reconstructing history from deployment logs.
A worked sizing example
Concrete arithmetic makes the trade-offs obvious. Take a documentation corpus: 50,000 documents, chunked into roughly 400,000 passages, embedded at 1,536 dimensions in single-precision floats.
- Raw vectors: 400,000 x 1,536 x 4 bytes, which is around 2.5GB.
- HNSW graph overhead adds meaningfully on top of that - budget roughly half again, so call it 3.5 to 4GB resident.
- Truncating to 768 dimensions roughly halves both figures, typically for a small recall cost that is worth measuring on your golden set.
- Binary quantisation with full-precision reranking cuts the searchable index dramatically again, at the cost of keeping the full vectors accessible for the rerank step.
The useful conclusion is that this workload fits comfortably on one well-specified instance, and pgvector would serve it without difficulty. The scale at which a dedicated store becomes necessary is considerably higher than most teams assume when they are choosing one.
Operational realities
For HNSW, the rough shape is: vector count times dimensions times bytes per value, plus a meaningful overhead for the graph structure itself. The practical consequences are that dimension count matters a great deal, and that many embedding models now support shortening the vector at modest accuracy cost - a lever worth testing before buying more memory.
Changing your embedding model means re-embedding the entire corpus. On a large collection that is hours of compute and a meaningful bill, and it is not a background detail - it is a migration with a plan.
Design for it: keep the source content addressable so you can re-embed without re-extracting, version your embeddings by model, and be able to run two indexes side by side during a cutover.
Some managed services snapshot for you; some do not, or do so on a plan you are not on. Confirm this explicitly rather than assuming. The mitigating factor is that vectors are derived data - if you have kept the source documents and the model version, you can rebuild, and that rebuild path should be tested rather than theoretical.
Namespace per tenant, filter per tenant, or collection per tenant. Namespaces isolate cleanly and can be expensive at high tenant counts; filtering is efficient and depends entirely on the filtering behaviour discussed above being correct. Whichever you choose, enforce it in one place rather than trusting every query, because the failure mode is one tenant retrieving another's documents.
How to actually choose
- Estimate your vector count at twelve months, not today. Below a few million, start with pgvector unless something specific rules it out.
- Write down your filtering pattern. If every query is scoped by tenant or permission, that constraint should drive the decision more than any benchmark.
- Decide whether you need hybrid search. If exact terms matter in your domain, you do.
- Be honest about operations. If nobody will own a self-hosted cluster, choose managed - an unmaintained open-source deployment is worse than a paid service.
- Benchmark the shortlist on your own data, with your own filters, at your own expected scale. Public benchmarks use clean datasets and unfiltered queries, which is not the workload you have.
One last observation. In the RAG systems we have worked on, the vector database has almost never been the limiting factor in answer quality. Chunking strategy, hybrid retrieval and reranking mattered far more. Choose a store that fits your constraints, then spend your remaining effort on retrieval quality - that is where the returns are.
