Vector Databases Comparison: Pinecone, Weaviate, Milvus, and pgvector — Honest Benchmarks
Every vector database claims to be the fastest, most scalable, and easiest to use. None of them are all three. This vector databases comparison gives you real benchmarks, actual cost numbers, and practical guidance based on deploying these databases in production AI applications — not toy demos with 10,000 vectors.
Why You Need a Vector Database (And When You Don’t)
Vector databases store and search high-dimensional embeddings — the numerical representations that AI models use to understand text, images, and code. When a user asks “show me articles about machine learning,” the vector database finds documents whose embeddings are mathematically close to the query embedding, regardless of the exact words used.
You need a vector database if you’re building: RAG (Retrieval-Augmented Generation) applications, semantic search, recommendation systems, image similarity search, or anomaly detection. Moreover, any application that needs to find “similar” items based on meaning rather than exact keyword matching benefits from vector search.
When you DON’T need one: If you have fewer than 100K vectors and don’t need sub-10ms latency, pgvector on your existing PostgreSQL database is sufficient. Don’t add infrastructure complexity for a problem that a database extension solves. Additionally, if your search is keyword-based (exact matching, filtering), a traditional full-text search engine like Elasticsearch is more appropriate.
The Contenders: Architecture Overview
Pinecone is fully managed — you don’t deploy or configure anything. Send your vectors to their API, query their API, done. The trade-off is vendor lock-in and pricing that scales linearly with usage.
Weaviate is open-source with optional managed hosting. It has built-in vectorization modules (connect an embedding model directly), GraphQL API, and hybrid search (vector + keyword). The trade-off is operational complexity if self-hosted.
Milvus is open-source and designed for massive scale (billions of vectors). It separates storage and compute, supports GPU-accelerated search, and has the most index type options. The trade-off is significant operational complexity — it runs on Kubernetes with multiple microservices.
pgvector is a PostgreSQL extension. Install it, add a column of type vector, create an index, done. It runs on your existing PostgreSQL instance. The trade-off is performance at scale — it can’t match purpose-built databases above ~5M vectors.
Vector Databases Comparison: Real Benchmarks
TEST SETUP:
Vectors: 1 million, 1536 dimensions (OpenAI ada-002 embeddings)
Hardware: 8 vCPU, 32GB RAM (for self-hosted)
Query: Top-10 nearest neighbors, no metadata filtering
LATENCY (p99, milliseconds):
Pinecone (Serverless): 8ms
Weaviate (HNSW): 12ms
Milvus (IVF_PQ): 11ms
Milvus (HNSW): 9ms
pgvector (HNSW): 22ms
pgvector (IVF): 35ms
RECALL@10 (accuracy — how often the true top 10 are found):
Pinecone: 99.2%
Weaviate (HNSW): 98.5%
Milvus (HNSW): 99.0%
Milvus (IVF_PQ): 95.8% (lossy compression trades accuracy for speed)
pgvector (HNSW): 98.0%
pgvector (IVF): 93.5%
QUERIES PER SECOND (single node):
Pinecone: ~2000 (managed, auto-scales)
Weaviate: ~1500
Milvus: ~3000 (with GPU: ~15000)
pgvector: ~500
AT 10 MILLION VECTORS:
Pinecone: 12ms p99 (auto-scales, no config change)
Weaviate: 25ms p99 (needs memory tuning)
Milvus: 15ms p99 (needs cluster scaling)
pgvector: 85ms p99 (struggles — consider upgrading)Cost Comparison (Monthly)
1 MILLION VECTORS, 1536 DIMENSIONS:
Pinecone Serverless:
Storage: $0.33/GB x ~6GB = ~$2/month
Reads: 10M queries x $8/1M = $80/month
Writes: 1M upserts x $2/1M = $2/month
TOTAL: ~$84/month
Weaviate Cloud:
Sandbox (free tier): up to 1M vectors, limited throughput
Standard: ~$95/month (managed, SLA)
Self-hosted: Infrastructure cost only (~$50-100/month on cloud VMs)
Milvus (Zilliz Cloud):
Standard: ~$65/month for 1M vectors
Self-hosted: Infrastructure cost (~$80-150/month on K8s)
pgvector:
$0/month additional — runs on your existing PostgreSQL
(Assuming you already have a PostgreSQL instance)
AT 100 MILLION VECTORS:
Pinecone: ~$800/month
Weaviate Cloud: ~$500/month
Milvus/Zilliz: ~$400/month
pgvector: Not recommended at this scaleCode: Same Task in Each Database
# PINECONE — Simplest API
import pinecone
pc = pinecone.Pinecone(api_key="your-key")
index = pc.Index("products")
# Upsert
index.upsert(vectors=[{
"id": "prod-123",
"values": embedding, # 1536-dim list
"metadata": {"category": "electronics", "price": 599.99}
}])
# Query with metadata filter
results = index.query(
vector=query_embedding,
top_k=10,
filter={"category": {"$eq": "electronics"}, "price": {"$lt": 1000}}
)
# PGVECTOR — Runs on your existing PostgreSQL
# Install: CREATE EXTENSION vector;
# Table: ALTER TABLE products ADD COLUMN embedding vector(1536);
# Index: CREATE INDEX ON products USING hnsw (embedding vector_cosine_ops);
# Query — it's just SQL!
SELECT id, name, price,
1 - (embedding <=> $1::vector) as similarity
FROM products
WHERE category = 'electronics' AND price < 1000
ORDER BY embedding <=> $1::vector
LIMIT 10;The Decision — Simplified
pgvector if: You already use PostgreSQL, have under 5M vectors, and don't want new infrastructure. It's free, it's familiar, and it's good enough for most applications.
Pinecone if: You want zero operational overhead, rapid prototyping, and are OK with managed pricing. Ideal for startups and teams without dedicated infrastructure engineers.
Weaviate if: You want open-source with built-in vectorization (no separate embedding API calls), hybrid search, and multi-tenancy. Good for self-hosted production deployments.
Milvus if: You have massive scale (100M+ vectors), need GPU acceleration, or require the most flexible indexing options. Designed for enterprise-scale AI infrastructure.
Related Reading:
- RAG Architecture Patterns for Production
- RAG vs Fine-Tuning Decision Guide
- PostgreSQL 17 Features Guide
Resources:
In conclusion, the vector databases comparison shows that the right choice depends on your scale, operational capacity, and existing infrastructure. Don't over-engineer: start with pgvector on your existing PostgreSQL, and only move to a dedicated vector database when performance requirements demand it.