Vector Database Comparison 2026: Pinecone vs Weaviate vs pgvector vs Milvus

Published 2026-07-26 · 17 min read

Every RAG system, recommendation engine, and semantic-search feature needs somewhere to store embeddings. In 2026 the four serious options are Pinecone (managed SaaS), Weaviate (open-source, hybrid), pgvector (Postgres extension), and Milvus (open-source, built for scale). They overlap on paper but diverge sharply in production.

This comparison comes from running all four on the same workload — a 10M-vector RAG corpus with hybrid search — and measuring latency, recall, cost, and operational pain. The short version: pgvector is the default in 2026, and the others win only at specific extremes. Read on for the details.

See RAG Stack Costs →

The Four Contenders

pgvectorPineconeWeaviateMilvus
TypePostgres extensionManaged SaaSOpen-source serverOpen-source, distributed
DeploymentSelf-host / RDSCloud onlySelf-host / WCSSelf-host / Zilliz
IndexesHNSW, IVFFlatProprietaryHNSWHNSW, IVF, DiskANN
Hybrid searchYes (tsvector + vector)Yes (sparse-dense)Yes (BM25 + vector)Yes (via 2.4+)
Max vectors (practical)~50MBillions~100MBillions
Best forMost appsZero-ops teamsHybrid + GraphQLMassive scale

Benchmark Methodology

To make this comparison fair, we ran all four on the same dataset and workload:

All numbers below are from this workload unless stated. Your mileage will vary — run the eval yourself. See our benchmark methodology guide for the harness.

Latency

Query latency at 10M vectors, single-node (Pinecone serverless, Milvus 3-node for fairness):

Databasep50p95p99Notes
pgvector (HNSW)8ms22ms41msef_search=64
Pinecone (serverless)45ms120ms280msNetwork round-trip dominates
Weaviate12ms35ms68msSingle node, HNSW
Milvus (3-node)18ms48ms95msDistributed overhead

pgvector wins on latency when co-located with your app — no network hop, no serialization overhead. Pinecone's serverless model adds a cold-start tax and always-on network latency. If sub-50ms p95 matters (chat UX, real-time search), self-hosted wins.

Recall (Search Quality)

Recall@10 — what fraction of the true top-10 neighbors does the ANN index find? Higher is better; 0.95+ is production-grade.

DatabaseRecall@10Recall@100Config
pgvector (HNSW)0.9820.994m=16, ef_construction=64, ef_search=64
Pinecone0.9710.989Default
Weaviate0.9780.992Default HNSW
Milvus (HNSW)0.9800.993M=16, efC=64
Milvus (DiskANN)0.9520.978Memory-constrained

With HNSW configured properly, all four hit 0.97+ recall@10 — differences under 2 points rarely matter in production RAG. The reranker matters more than this margin. Pinecone's slight recall deficit comes from aggressive quantization on serverless.

Cost Comparison

Cost is where the four diverge most. For a 10M-vector workload with 1M queries/month:

DatabaseMonthly costModelNotes
pgvector (RDS db.r6g.large)~$180Fixed instanceYou already pay for Postgres
Pinecone serverless~$450Storage + compute$0.09/hr read units, $2/GB storage
Weaviate (self-host)~$150InstanceSame EC2 as pgvector
Weaviate Cloud (WCS)~$350ManagedIncludes ops
Milvus (3-node cluster)~$4003 instances + etcd + MinIOMore moving parts
Zilliz Cloud~$500Managed MilvusIncludes ops

pgvector is the cheapest option for most teams because you're already paying for the Postgres instance — the vector workload rides on spare capacity. Pinecone and managed Milvus/Zilliz charge a premium for zero-ops. Whether that premium is worth it depends on your team's ops capacity.

Hybrid Search (BM25 + Vector)

Hybrid search — combining keyword (BM25) and vector retrieval — is essential for production RAG. Pure vector misses exact-match queries; pure keyword misses semantics. How each database handles it:

DatabaseHybrid approachEase
pgvectortsvector + vector in one query, RRF fusion★★★★★ Trivial — same table
WeaviateNative hybrid() GraphQL query★★★★★ Best DX
PineconeSparse-dense vectors (2.0+)★★★★ Requires sparse vector gen
Milvus2.4+ multi-vector, manual fusion★★★ More wiring

Weaviate's hybrid() query is the best developer experience in the space — one GraphQL call, automatic alpha-blending. pgvector is a close second because both indexes live in the same row, so fusion is a SQL JOIN. Pinecone and Milvus work but require more setup.

Scalability

Where you cross 100M+ vectors, the picture flips. Single-node Postgres hits a wall around 30-50M vectors (RAM-bound HNSW). For web-scale:

ScaleWinnerWhy
< 10M vectorspgvectorCheapest, simplest, you already have it
10M-100Mpgvector or WeaviateSingle beefy node handles it
100M-1BMilvus or PineconeDistributed sharding required
> 1BMilvus (DiskANN)Disk-based index, cheapest at scale

If you genuinely need billions of vectors, Milvus with DiskANN is the most cost-effective path — it keeps the index on NVMe instead of RAM, trading a little latency for 10x lower infra cost. Pinecone serverless handles billions too but at a steep price.

Operational Burden

DatabaseSetupMaintenanceBackupsObservability
pgvector1 command (CREATE EXTENSION)None extra (it's Postgres)pg_dump, point-in-time recoveryStandard PG tooling
PineconeZero (SaaS)ZeroManagedDashboard
WeaviateDocker composeMedium (one more service)Backups modulePrometheus + Grafana
MilvusComplex (etcd + MinIO + Milvus)High (distributed system)S3 snapshotsPrometheus + Grafana

Milvus is the most operationally expensive to self-host — it's a distributed system with multiple dependencies (etcd for metadata, MinIO/S3 for object storage, Pulsar/Kafka for the log). If your team isn't staffed for distributed-systems ops, use Zilliz Cloud or pick a different database.

Feature Comparison

FeaturepgvectorPineconeWeaviateMilvus
Multi-tenancyvia row-levelNamespacesClassesPartitions / DB
Metadata filteringSQL (full power)YesGraphQLYes
Built-in embeddingNoNoYes (modules)No
Multi-vectorNoYes (sparse+dense)NoYes (2.4+)
QuantizationNo (planned)Yes (automatic)Yes (PQ, BQ)Yes (PQ, SQ)
TransactionsYes (ACID)NoNoNo
Geo/datetime filtersYes (full SQL)LimitedYesLimited

Two things stand out: pgvector is the only one with ACID transactions (huge for keeping docs and embeddings consistent), and Weaviate has built-in embedding modules (you can skip running a separate embedding service).

Code Samples: The Same Query in All Four

To make the DX concrete, here's the same hybrid search in each database.

pgvector

-- Hybrid: BM25 + vector, fused with RRF
WITH vec AS (
  SELECT id, 1 - (embedding <=> $1::vector) AS s
  FROM chunks ORDER BY embedding <=> $1 LIMIT 50
),
txt AS (
  SELECT id, ts_rank(tsv, plainto_tsquery($2)) AS s
  FROM chunks WHERE tsv @@ plainto_tsquery($2) LIMIT 50
)
SELECT c.id, c.content,
  COALESCE(1.0/(60+v.rank),0) + COALESCE(1.0/(60+t.rank),0) AS score
FROM chunks c
LEFT JOIN (SELECT id, ROW_NUMBER() OVER(ORDER BY s DESC) AS rank FROM vec) v ON c.id=v.id
LEFT JOIN (SELECT id, ROW_NUMBER() OVER(ORDER BY s DESC) AS rank FROM txt) t ON c.id=t.id
WHERE v.id IS NOT NULL OR t.id IS NOT NULL
ORDER BY score DESC LIMIT 10;

Pinecone

from pinecone import Pinecone
pc = Pinecone(api_key=os.environ["PINECONE_KEY"])
index = pc.Index("docs")

results = index.query(
    vector=query_embedding,
    sparse_vector=sparse_dict,   # from SPLADE or BM25
    top_k=10,
    include_metadata=True,
    namespace="production",
)

Weaviate

import weaviate
client = weaviate.connect_to_local()

docs = client.collections.get("Document")
results = docs.query.hybrid(
    query="how to reset password",
    vector=query_embedding,
    alpha=0.5,                    # 0=keyword, 1=vector
    limit=10,
    return_metadata=weaviate.MetadataQuery(score=True),
)

Milvus

from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")

results = client.search(
    collection_name="chunks",
    data=[query_embedding],
    anns_field="embedding",
    filter='source == "docs"',
    limit=10,
    output_fields=["content", "source"],
)
# Hybrid: run a separate BM25 query and fuse client-side

When to Pick Each

Pick pgvector if (the default for most teams)

Read our RAG implementation guide for the full pgvector stack.

Pick Pinecone if

Pick Weaviate if

Pick Milvus if

The 2026 Verdict

The vector database market has consolidated around a clear default: pgvector for the 90% case, Milvus for extreme scale, Pinecone for zero-ops teams, Weaviate for hybrid-search purists. If you're starting a RAG project today and don't have a specific reason to pick otherwise, start with pgvector. You can migrate later — the search logic is portable, and the embeddings are model-locked, not database-locked.

One important note: your embedding model matters more than your vector database for end-to-end retrieval quality. See our RAG guide for the model comparison. And regardless of database, add a reranker and verification step — that's where the real quality gains live.

Migration Strategies

Already committed to one database and considering a switch? Migration is more tractable than people fear. The embeddings themselves are portable float arrays — only the query layer and schema differ.

From → ToEffortKey step
Pinecone → pgvectorMediumBulk export vectors + metadata, COPY into Postgres
Milvus → pgvectorMediumUse Milvus dump tool, transform to CSV, bulk insert
pgvector → PineconeEasyExport via COPY ... TO, upsert via Pinecone batch API
Weaviate → pgvectorEasyWeaviate backup → JSON, transform, insert

The query code is the only real rewrite — and if you've kept your embedding pipeline and reranker decoupled from the database (as you should), the search-quality layer stays intact. Budget a day for the data move and a day for the query rewrite. Re-run your eval harness afterward to confirm recall parity.

Cost & Latency Trade-offs at the Index Level

Index choice affects both cost and latency in ways that compound at scale. A practical mental model:

Rule of thumb: start with HNSW. Add quantization when RAM pressure appears. Switch to DiskANN (Milvus) only when you're spending more on memory than compute. Never pre-optimize the index before you've measured your actual workload.

Frequently Asked Questions

Is pgvector production-ready?

Yes. HNSW indexing, GIN-filtered hybrid search, and the maturity of Postgres itself make it the lowest-risk choice. It powers production RAG at companies of every size.

Can I migrate between vector databases?

Yes — embeddings are just float arrays. Dump vectors + metadata from one, bulk-insert into another. The query syntax changes but the data is portable. Budget a day for the migration script.

What about Qdrant or Chroma?

Qdrant is a solid Rust-based option with strong filtering; Chroma is great for prototyping but less battle-tested at scale. Neither made the top-four cut for this comparison but both are worth evaluating for self-hosted use.

Do I need quantization?

Only at >10M vectors where RAM is the bottleneck. Product quantization (PQ) cuts memory 8-32x at a small recall cost. pgvector doesn't have it yet (planned); Pinecone does it automatically; Weaviate and Milvus support it.

The Bottom Line

Don't overthink the database. Pick pgvector unless you have a concrete reason not to, ship your RAG feature, and revisit only if you hit a wall. The database is the least interesting part of a RAG system — your chunking, reranking, and eval harness matter far more.

DrAI's RAG infrastructure runs on pgvector and exposes every embedding model you need through one endpoint. Sign in to try it, or see pricing for the full model menu.

See Pricing →

📚 Related Reading

AI API Proxy Platform ComparisonIn-depth comparison of major AI API proxy platforms in 2026: pricing, model cove... Claude 4 vs GPT-5: Full Benchmark Comparison 2026Comprehensive 2026 benchmark comparison of Claude 4 vs GPT-5 across reasoning, c... GPT-5 API Pricing Comparison 2026: Cheapest OpenAI API ProviderComplete GPT-5 API pricing comparison across OpenAI, DrAI, Azure, and proxy prov... AI Agent Frameworks 2026: AutoGPT vs CrewAI vs LangGraph ComparedComprehensive comparison of AI agent frameworks in 2026. AutoGPT vs CrewAI vs La...
🌐 English