RAGStackGuide
Flat isometric illustration of a pink cube on a lilac plinth with a glowing funnel pouring into it, flanked by two stacks of lavender database discs.
vector-databases

Qdrant vs Milvus vs Pinecone: Vector DB Comparison

How Qdrant, Milvus and Pinecone differ on deployment, index types, quantisation, filtering and hybrid search, and which one fits which kind of RAG workload.

By RAGStackGuide Editorial · · 7 min read

Qdrant, Milvus and Pinecone are the three stores most RAG shortlists come down to, and the choice between them is almost never decided by raw query speed. All three are fast enough for typical retrieval workloads at typical corpus sizes. What separates them is the deployment model, how filtering interacts with the index, and how much operational surface you are willing to own.

The short version: Pinecone if you want no infrastructure, Qdrant if you want a single self-hosted service with strong filtered search, Milvus if you are heading for very large scale or need index types the others do not offer.

Comparison at a glance

QdrantMilvusPinecone
LicenseApache 2.0Apache 2.0Proprietary
Self-hostingYes, single binaryYes, standalone or distributedNo
Managed optionQdrant CloudZilliz CloudPinecone (managed only)
Written inRustGo and C++Not disclosed
Index typesHNSWHNSW, IVF family, DiskANN, GPU indexesManaged, not user-selected
QuantisationScalar, product, binaryScalar, product, binaryManaged
Sparse vectorsYesYesYes
Hybrid fusionBuilt in, RRF and DBSFBuilt in, RRF and weightedBuilt in
FilteringFilter applied during graph traversalPartition and scalar filteringMetadata filtering with namespaces
Local dev storyDocker image or in-memory clientMilvus Lite, embeddedCloud only
Best fitFilter-heavy retrieval, small ops teamVery large or multi-tenant corporaTeams with no infrastructure appetite

Everything below explains what those rows actually cost you.

The deployment split is the real decision

Pinecone is a managed service and only a managed service. There is no self-hosted build, no air-gapped option, and no way to run it on your own hardware. For a team that does not want to operate a database, that is the entire value proposition and it is a legitimate one: no capacity planning, no index parameter tuning, no upgrade windows.

The cost is structural rather than financial. Data lives on someone else’s infrastructure, which is a hard stop for regulated corpora. Cost scales with usage under a pricing model you do not control. And the index is a black box, so when recall is poor you cannot inspect or retune the underlying structure the way you can with an open store.

Qdrant and Milvus are both Apache 2.0 and both run on your own hardware, but the operational shapes differ sharply. Qdrant is a single Rust binary with an embedded storage engine: one container, one config file, and an in-memory Python client for tests. Milvus in its distributed form is a cluster of separate components with external dependencies for object storage and messaging, which is what makes it scale horizontally and also what makes it heavier to run. Milvus Lite exists for local development and small embedded use, so the on-ramp is gentler than the production topology suggests.

If nobody on the team wants to own a distributed system, that difference decides it.

Index types and what they buy

Qdrant standardises on HNSW. That is a deliberate simplification: HNSW is the best general-purpose approximate index for typical RAG corpora, and there is no index-selection decision to get wrong.

Milvus exposes a much wider catalogue: the IVF family for memory-efficient partitioned search, HNSW for graph search, DiskANN for corpora larger than RAM, and GPU-accelerated indexes. That breadth is why Milvus turns up in very large deployments. It is also a real cost, because choosing badly among them produces worse recall than the default would have.

Pinecone does not expose index selection at all. You choose a metric and a dimension count; the rest is managed.

Three practical notes cut across all of them:

  • Below roughly a million vectors, index choice barely matters. A flat exact scan is fast enough and gives perfect recall. Use it as the reference point that tells you what an approximate index is actually costing you in recall.
  • Budget more RAM than the vectors alone need. Qdrant’s capacity planning guide sizes an in-memory collection at vectors x dimensions x 4 bytes x 1.5; the extra 50 percent covers index structures, point versions and temporary segments created during optimisation, and payload and replicas are additional again. The chunk and index sizing calculator applies the same multiplier.
  • Quantisation is the main lever on cost. Scalar quantisation to 8-bit cuts vector storage roughly fourfold for a small recall penalty. Binary quantisation goes far further with a much larger penalty, usually paired with a rescoring pass over full-precision vectors. Qdrant and Milvus both expose scalar, product and binary quantisation directly; on Pinecone this is a managed concern.

Filtering is where the stores genuinely differ

Most production RAG queries are filtered queries: this product version, this tenant, this language, this access level. How a store implements that filter matters more than its unfiltered throughput.

The naive implementations are both bad. Post-filtering runs the vector search, then discards non-matching results, so a selective filter can empty the result set entirely and restricted chunks consume top-k slots that should have held the answer. Pre-filtering builds the candidate set from the filter first, then scans it exactly, which is correct but degenerates to brute force when the filter matches a large subset.

Qdrant’s answer is a filterable HNSW: the filter is evaluated during graph traversal, and the graph is built with additional links so that connectivity survives when a filter removes most nodes. That is why Qdrant tends to be the recommendation for filter-heavy retrieval. Milvus approaches the same problem through partitions and partition keys, which physically separate data so that a tenant or category query searches only its own segment: excellent when the filter dimension is known in advance and coarse, less flexible for ad-hoc filters. Pinecone offers metadata filtering plus namespaces, with namespaces serving the same multi-tenancy role as Milvus partitions.

Whichever store you pick, verify the filter runs inside the search rather than over its output. A system that post-filters silently loses recall exactly on the queries that matter most.

Dense vectors are weak on exact tokens: error codes, part numbers, SKUs, function names. Hybrid search runs a lexical or sparse index alongside the dense one and fuses the result lists.

All three stores now support this natively rather than requiring a separate lexical engine. Qdrant handles it through sparse vectors with a fusion query, offering reciprocal rank fusion and distribution-based score fusion. Milvus supports sparse vectors with RRF and weighted ranking. Pinecone supports sparse-dense hybrid within its managed API.

Reciprocal rank fusion is the usual default because it needs no score normalisation between two systems with incompatible score ranges, summing 1 / (k + rank) across lists with k = 60 as the conventional constant. Weighted fusion can beat it, but only after you have a measurement to weight against.

Benchmarks: how to read them

Every vendor publishes benchmarks and every set of benchmarks favours the vendor that published it. Two tools are worth more than the marketing pages: ANN-Benchmarks for the underlying algorithms, and VectorDBBench for the databases themselves, which is open source and reproducible even though Zilliz maintains it.

Three rules for reading any of them:

  1. Recall and QPS are a single curve, not two numbers. Any store can be made fast by lowering ef and any store can be made accurate by raising it. A throughput figure quoted without its recall figure means nothing.
  2. Filtered benchmarks are the relevant ones. Unfiltered top-k over a public dataset is not the query your application sends.
  3. Dataset shape dominates. Results on a 1M-vector 768-dimension public set do not transfer to a 100M-vector 3072-dimension corpus.

For most RAG workloads, all three stores land within a range where the difference is invisible next to the recall gained by fixing chunking or adding a reranker.

Choosing

  • Pinecone when the team has no appetite for infrastructure, the corpus has no data-residency constraint, and predictable operations are worth more than control.
  • Qdrant when you want one self-hosted service, filtering is central to your queries, and the team is small. It is the lowest-ceremony open option.
  • Milvus when the corpus is very large, growth is horizontal, you need DiskANN or GPU indexes, or partition-level multi-tenancy maps onto your data model.

Postgres with pgvector deserves a mention as the fourth option nobody shortlists. If the corpus is modest and the data already lives in Postgres, one fewer system to operate frequently beats any of the above. Note the ceiling: pgvector stores vectors up to 16,000 dimensions but will not build an HNSW index above 2,000.

Whichever store you choose, it is not the thing that decides retrieval quality. Chunking sets the ceiling and evaluation tells you where you are against it. Start with the chunking strategy guide, place the store correctly in the RAG pipeline build order, and when results are wrong work through the retrieval debugging checklist before blaming the database.

See also

Sources

  1. Qdrant: Indexing concepts
  2. Milvus: Index explained
  3. Pinecone: Indexing overview
  4. Qdrant: Capacity planning
  5. pgvector: index and vector dimension limits
  6. VectorDBBench: open-source vector database benchmark
#rag #vector-search #vector-databases#qdrant#milvus#pinecone #retrieval

Related