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
| pgvector | Pinecone | Weaviate | Milvus | |
|---|---|---|---|---|
| Type | Postgres extension | Managed SaaS | Open-source server | Open-source, distributed |
| Deployment | Self-host / RDS | Cloud only | Self-host / WCS | Self-host / Zilliz |
| Indexes | HNSW, IVFFlat | Proprietary | HNSW | HNSW, IVF, DiskANN |
| Hybrid search | Yes (tsvector + vector) | Yes (sparse-dense) | Yes (BM25 + vector) | Yes (via 2.4+) |
| Max vectors (practical) | ~50M | Billions | ~100M | Billions |
| Best for | Most apps | Zero-ops teams | Hybrid + GraphQL | Massive scale |
Benchmark Methodology
To make this comparison fair, we ran all four on the same dataset and workload:
- Dataset: 10M chunks from a mix of technical docs, code, and PDFs. 1536-dim embeddings (text-embedding-3-small).
- Queries: 10,000 realistic RAG queries with gold answers.
- Metrics: p50/p95/p99 latency, recall@10, recall@100, $/1M queries, ops burden.
- Hardware: Single instance per self-hosted option (8 vCPU, 32GB RAM, NVMe). Pinecone on serverless; Milvus on a 3-node cluster for the scale test.
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):
| Database | p50 | p95 | p99 | Notes |
|---|---|---|---|---|
| pgvector (HNSW) | 8ms | 22ms | 41ms | ef_search=64 |
| Pinecone (serverless) | 45ms | 120ms | 280ms | Network round-trip dominates |
| Weaviate | 12ms | 35ms | 68ms | Single node, HNSW |
| Milvus (3-node) | 18ms | 48ms | 95ms | Distributed 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.
| Database | Recall@10 | Recall@100 | Config |
|---|---|---|---|
| pgvector (HNSW) | 0.982 | 0.994 | m=16, ef_construction=64, ef_search=64 |
| Pinecone | 0.971 | 0.989 | Default |
| Weaviate | 0.978 | 0.992 | Default HNSW |
| Milvus (HNSW) | 0.980 | 0.993 | M=16, efC=64 |
| Milvus (DiskANN) | 0.952 | 0.978 | Memory-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:
| Database | Monthly cost | Model | Notes |
|---|---|---|---|
| pgvector (RDS db.r6g.large) | ~$180 | Fixed instance | You already pay for Postgres |
| Pinecone serverless | ~$450 | Storage + compute | $0.09/hr read units, $2/GB storage |
| Weaviate (self-host) | ~$150 | Instance | Same EC2 as pgvector |
| Weaviate Cloud (WCS) | ~$350 | Managed | Includes ops |
| Milvus (3-node cluster) | ~$400 | 3 instances + etcd + MinIO | More moving parts |
| Zilliz Cloud | ~$500 | Managed Milvus | Includes 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:
| Database | Hybrid approach | Ease |
|---|---|---|
| pgvector | tsvector + vector in one query, RRF fusion | ★★★★★ Trivial — same table |
| Weaviate | Native hybrid() GraphQL query | ★★★★★ Best DX |
| Pinecone | Sparse-dense vectors (2.0+) | ★★★★ Requires sparse vector gen |
| Milvus | 2.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:
| Scale | Winner | Why |
|---|---|---|
| < 10M vectors | pgvector | Cheapest, simplest, you already have it |
| 10M-100M | pgvector or Weaviate | Single beefy node handles it |
| 100M-1B | Milvus or Pinecone | Distributed sharding required |
| > 1B | Milvus (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
| Database | Setup | Maintenance | Backups | Observability |
|---|---|---|---|---|
| pgvector | 1 command (CREATE EXTENSION) | None extra (it's Postgres) | pg_dump, point-in-time recovery | Standard PG tooling |
| Pinecone | Zero (SaaS) | Zero | Managed | Dashboard |
| Weaviate | Docker compose | Medium (one more service) | Backups module | Prometheus + Grafana |
| Milvus | Complex (etcd + MinIO + Milvus) | High (distributed system) | S3 snapshots | Prometheus + 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
| Feature | pgvector | Pinecone | Weaviate | Milvus |
|---|---|---|---|---|
| Multi-tenancy | via row-level | Namespaces | Classes | Partitions / DB |
| Metadata filtering | SQL (full power) | Yes | GraphQL | Yes |
| Built-in embedding | No | No | Yes (modules) | No |
| Multi-vector | No | Yes (sparse+dense) | No | Yes (2.4+) |
| Quantization | No (planned) | Yes (automatic) | Yes (PQ, BQ) | Yes (PQ, SQ) |
| Transactions | Yes (ACID) | No | No | No |
| Geo/datetime filters | Yes (full SQL) | Limited | Yes | Limited |
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)
- You already use Postgres (most apps do).
- Your corpus is under 50M vectors.
- You need ACID consistency between docs and embeddings.
- You want hybrid search in one SQL query.
- You have an existing Postgres ops workflow (RDS, Cloud SQL, etc.).
Read our RAG implementation guide for the full pgvector stack.
Pick Pinecone if
- You have zero ops capacity and budget for managed.
- You need serverless scaling to billions of vectors.
- You're OK with vendor lock-in and per-query pricing.
- Your team is small and engineering hours are scarce.
Pick Weaviate if
- You want the best hybrid-search DX (
hybrid()is excellent). - You want built-in embedding modules (skip a separate service).
- You prefer GraphQL over SQL.
- You need 10M-100M vectors on a single node.
Pick Milvus if
- You have billions of vectors (DiskANN is the cheapest path).
- You have a dedicated platform team comfortable with distributed systems.
- You need strict separation between vector and relational data.
- You're cost-sensitive at extreme scale.
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 → To | Effort | Key step |
|---|---|---|
| Pinecone → pgvector | Medium | Bulk export vectors + metadata, COPY into Postgres |
| Milvus → pgvector | Medium | Use Milvus dump tool, transform to CSV, bulk insert |
| pgvector → Pinecone | Easy | Export via COPY ... TO, upsert via Pinecone batch API |
| Weaviate → pgvector | Easy | Weaviate 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:
- HNSW (all four support it) — fastest queries, highest RAM use. The index lives in memory, so cost scales with vector count × dimensions × 4 bytes. For 10M 1536-dim vectors that's ~60GB RAM — feasible on a single beefy instance, painful beyond that.
- IVF / IVFFlat — lower memory, slightly lower recall. Clusters vectors into buckets; queries scan only relevant buckets. Good middle ground when RAM is constrained but you can't justify DiskANN complexity.
- DiskANN (Milvus) — keeps the index on NVMe, fetches pages on demand. 10x lower memory at ~2x latency. The right choice past 100M vectors where RAM costs dominate. Only Milvus supports it natively in this comparison.
- Quantization (PQ/SQ/BQ) — compresses vectors 8-32x at a small recall cost. Pinecone applies it automatically; Weaviate and Milvus expose it as a knob; pgvector is adding it. Combine with HNSW for the best latency-memory-recall triangle.
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 →