A wrong vector database choice costs you 3-8x in infrastructure. One team burned $4,200/month on Pinecone serverless for a workload pgvector handles on a $40 instance. Another deployed default HNSW parameters and hit production only to find queries running 50x slower than ten minutes of tuning would have fixed.
The vector database is not a commodity. Index architecture and filter strategy shape latency and recall as much as your embedding model. Each database below has one specific failure mode you need to know before choosing — not after deploying.
Pinecone: Zero-Ops, Fastest Time-to-Production
Pinecone’s pitch is simple: you never think about infrastructure. No m and ef_construction parameters. No index rebuilds during bulk loading. No CREATE INDEX CONCURRENTLY gymnastics to avoid write locks. You create an index, you insert vectors, you query. Everything else is handled.
Where Pinecone wins: developer experience. The documentation is the best in the category. The serverless indexing means you don’t provision hardware — you pay per operation. Native hybrid search combines dense vectors with sparse (BM25) retrieval without requiring separate infrastructure. For teams that want RAG working today, not next week, Pinecone delivers.
Where Pinecone loses: cost at scale. At 10 million vectors with moderate query volume, Pinecone is competitive. At 100 million vectors with high query throughput, it’s 3-8× more expensive than self-hosted pgvector. The convenience is real. The premium is real. Know which matters more for your budget.
Best for: teams without existing database infrastructure, early-stage products optimizing for speed-to-market, workloads where operational simplicity outweighs infrastructure cost.
For a full RAG deployment walkthrough that works with any vector database, see our RAG production implementation guide.
pgvector: The PostgreSQL Native
If your team already runs PostgreSQL, you have a vector database. One command: CREATE EXTENSION vector; (see the pgvector documentation for installation details). Zero new infrastructure. Zero new services to monitor. Zero new authentication systems to integrate.
CREATE EXTENSION vector;
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536)
);
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
HNSW indexing delivers sub-10ms queries at up to roughly 10 million chunks. The killer feature: hybrid search in one SQL query. tsvector for keyword matching, <=> for vector similarity, combined with UNION and ranked — no separate search infrastructure.
Critical performance note: drop the HNSW index before bulk loading. HNSW indexing at insert time is an order of magnitude slower than brute force insertion. Load your data, then CREATE INDEX CONCURRENTLY to avoid blocking writes. This one workflow detail separates “pgvector is fast” from “pgvector is unusably slow” — and it’s buried in documentation that most teams skip.
Best for: teams already on PostgreSQL, workloads under 10 million vectors, multi-tenant applications where vector data lives alongside relational data in the same database.
Weaviate: Hybrid Search as a First-Class Citizen
Weaviate was built for hybrid search before hybrid search was table stakes. BM25 + vector retrieval is native, not bolted on. The GraphQL API gives you expressive, composable queries. Modules support OpenAI, Cohere, and self-hosted embedding — useful when embeddings and vector storage need to live behind the same VPC boundary.
v1.28.0 added first-class support for self-hosted embeddings via llama.cpp. If you need data sovereignty — embeddings and storage both on-prem — Weaviate is the smoothest integrated option.
Where Weaviate loses: operational complexity for self-hosted deployments. You’re managing another stateful service. For teams already stretched thin on infrastructure, this is real overhead.
Best for: applications where hybrid search is the primary retrieval pattern, teams that want GraphQL-native querying, deployments that need embeddings and storage co-located.
If hybrid search is central to your retrieval architecture, our hybrid search and reranking implementation guide covers the query-side patterns that complement your vector database.
Qdrant: Performance-First, Rust-Engineered
Qdrant is the fastest of the four on raw query throughput — written in Rust, optimized for vector operations at the language level. The filter query language is the most expressive in the category. If your RAG pipeline requires complex pre-retrieval filters — tenant ID, date range, document type, access level, language — Qdrant handles them with less latency overhead than the alternatives.
Quantization support is built in: scalar, product, and binary quantization compress vectors for faster approximate search with configurable recall trade-offs. For high-throughput, cost-sensitive deployments, this is a meaningful advantage.
Where Qdrant loses: smaller community, fewer managed service options, steeper learning curve for teams without Rust infrastructure experience.
Best for: high-throughput deployments, applications with complex metadata filtering requirements, teams comfortable with infrastructure management who prioritize query performance.
Decision Tree & HNSW Tuning
The decision tree, in priority order:
- Already running PostgreSQL? → pgvector. Zero new infrastructure. Start today.
- Need to ship this week with zero ops? → Pinecone. Pay the premium for speed.
- Hybrid search is your primary retrieval pattern? → Weaviate. Built for it from day one.
- Complex metadata filtering + high throughput? → Qdrant. The filter performance gap is real.
- Data sovereignty required for embeddings AND storage? → Weaviate + self-hosted embeddings or pgvector + self-hosted bge-m3.
For a walkthrough of setting up your first vector-capable endpoint and making your first similarity query, see the step-by-step quickstart.
HNSW tuning — the 10-minute investment that pays back forever:
| Parameter | What It Does | Start Here | Tune When |
|---|---|---|---|
m | Edges per node in the HNSW graph | 16 | Recall < target → increase to 32, 64 (costs memory) |
ef_construction | Search depth during index building | 64 | Index build too slow → decrease to 32. Recall too low → increase to 128 |
ef_search | Search depth during queries | 40 | Query too slow → decrease. Recall too low → increase to 100, 200 |
The trade-off is always memory vs. speed vs. recall. Higher m and ef values improve recall at the cost of more memory and slower builds/queries. Start with the defaults above. Run 50 test queries. If recall is below target, increase ef_search first — it’s a query-time setting, no re-indexing required.
Vector DB Mistakes That Cost You in Production
Building HNSW indexes during insert. This is the single most common pgvector performance complaint — and it’s entirely self-inflicted. HNSW indexing at insert time is 10-50× slower than brute-force insertion because every new vector triggers graph reorganization. The fix: drop the index, bulk load, then CREATE INDEX CONCURRENTLY. This one workflow change moves pgvector from “unusable at scale” to “sub-10ms queries at 10M vectors.”
Default m and ef_construction values. Every vector database ships with conservative HNSW defaults optimized for fast index builds, not query performance. The m=16, ef_construction=64 starting point in the table above will outperform defaults by 20-40% on query latency with zero infrastructure changes. Ten minutes of parameter tuning. Permanent performance gain.
Treating all four databases as interchangeable. They aren’t. Pinecone’s serverless architecture means cold starts on infrequently queried namespaces — your first query after an idle hour can take 500ms. pgvector’s CONCURRENTLY index builds don’t block reads but double your storage during the build. Weaviate’s GraphQL API is powerful but means every query goes through a GraphQL parser — 5-15ms of overhead per request. Qdrant’s Rust performance advantage disappears if you’re network-bound rather than CPU-bound. The database choice matters less than understanding your database’s specific failure mode.
Further reading. Vector databases are one piece of the RAG stack. For the embeddings that feed your vector store, compare options in the embeddings API overview.
FAQ
I already have PostgreSQL. Do I really need Pinecone?
No. CREATE EXTENSION vector; and you have a production-capable vector database. pgvector handles up to ~10 million vectors with sub-10ms queries on modest hardware. The cases where you’d add Pinecone on top of an existing Postgres deployment: you’ve outgrown pgvector’s scale (>50M vectors), you need serverless scaling without managing database connections, or your team lacks the PostgreSQL expertise to tune HNSW indexes.
How many vectors can pgvector handle?
With HNSW indexing and appropriate m/ef tuning, pgvector comfortably handles 10 million vectors with sub-10ms p95 query latency on a single instance. Beyond 50 million, consider partitioning or migration to a dedicated vector database. The exact ceiling depends on your dimensionality: 256-dimensional vectors go ~6× further than 1536-dimensional vectors on the same hardware.
Managed vs. self-hosted vector DB — what’s the TCO difference?
Pinecone serverless: $0.33 per 1M reads, $1.45 per 1M writes. At 1M queries/month with 10M vectors, roughly $70-150/month. Self-hosted pgvector on a $40/month DB instance: roughly $40-80/month including backups. The gap widens with scale. At 100M vectors, Pinecone can exceed $1,500/month while pgvector on dedicated hardware might cost $200-400/month — but you’re now managing that hardware.
How hard is it to migrate from Pinecone to pgvector?
The migration itself is straightforward — export vectors as JSON, transform to SQL INSERT statements, re-index. The real work isn’t the migration. It’s setting up the PostgreSQL infrastructure, configuring backups, establishing monitoring, and building the operational knowledge to tune HNSW indexes. If your team already manages PostgreSQL, the migration is a weekend project. If not, the operational learning curve is the real cost — not the data movement.
For cost benchmarking across the full LLM stack including embeddings, chat, and storage, our API pricing comparison across providers covers every dimension.
How do I know when I’ve outgrown pgvector?
Watch two metrics: p95 query latency and index build time. When p95 latency exceeds 50ms with properly tuned HNSW parameters, or when a full re-index takes longer than your maintenance window, you’ve hit pgvector’s practical ceiling. For most teams, this happens around 30-50 million vectors on a single instance. Before migrating, try reducing dimensionality first — switching from 1536 to 256 dimensions effectively gives you 6× more headroom on the same hardware.
What embedding dimensionality does to your vector DB bill
Every embedding model outputs a default number of dimensions — 1536 for OpenAI text-embedding-3-small, 1024 for Cohere and Voyage, 3072 for text-embedding-3-large. That number multiplies directly into your storage and query costs. A 256-dimensional vector uses 1/6 the storage of a 1536-dimensional vector and queries proportionally faster. Before upgrading your vector database instance to handle “slow queries,” check whether you’re indexing 1536-dimensional vectors when 256 would produce near-identical retrieval quality. OpenAI’s dimensions parameter makes this a one-line change. It’s the cheapest performance optimization most teams never apply.
Your vector database choice should be boring. Pick the one that fits your existing infrastructure, scales to your projected volume for the next 18 months, and doesn’t require a new engineering hire to operate. For most teams, that’s pgvector — because most teams already run PostgreSQL. For everyone else, the decision tree above gives you the answer.
Your vector database and your LLM API, billed together. Set up your TokSpan endpoint — embeddings and chat through one integration, regardless of which vector database sits behind them.