Vector Databases Compared: Pinecone, Qdrant, Weaviate
# Choosing a vector database in 2026 comes down to operational simplicity, query performance, and cost. This side-by-side comparison of Pinecone, Qdrant, Weaviate, and pgvector saves you weeks of evaluation.
Vector databases are the backbone of every RAG system. The wrong choice costs you in operational complexity, query latency, or monthly bills. This comparison covers the four most-used options in production AI systems in 2026: Pinecone, Qdrant, Weaviate, and pgvector — what each excels at, and when each loses.
The Comparison Matrix
| Feature | Pinecone | Qdrant | Weaviate | pgvector | |---------|---------|-------|---------|---------| | Deployment | Managed only | Self-hosted / Cloud | Self-hosted / Cloud | Self-hosted | | Free tier | 2GB | Unlimited (self-host) | Unlimited (self-host) | Unlimited | | Dimensions | Up to 20,000 | Up to 65,535 | Up to 65,535 | Up to 16,000 | | Metadata filtering | Good | Excellent | Excellent | SQL filters | | Hybrid search | Limited | Native (v1.7+) | Native | Manual | | Language SDKs | Python, JS, Go | Python, JS, Go, Rust | Python, JS, Go | Any Postgres driver | | ACID transactions | No | No | No | Yes (Postgres) | | Approximate algorithm | HNSW | HNSW | HNSW | HNSW / IVFFlat | | Latency (p99, 1M vecs) | ~20ms | ~5ms | ~8ms | ~30ms |
Pinecone: Best for Getting Started Fast
Pinecone's strength is zero operational overhead. No infrastructure to manage, no tuning required. You create an index, upsert vectors, query — done.
import { Pinecone } from "@pinecone-database/pinecone";
const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });
// Create index
await pc.createIndex({
name: "knowledge-base",
dimension: 1536,
metric: "cosine",
spec: { serverless: { cloud: "aws", region: "us-east-1" } },
});
const index = pc.index("knowledge-base");
// Upsert
await index.upsert([
{ id: "doc1", values: embedding, metadata: { text: "...", source: "api-docs" } },
]);
// Query
const results = await index.query({
vector: queryEmbedding,
topK: 5,
includeMetadata: true,
filter: { source: { $eq: "api-docs" } },
});
Use Pinecone when: you want managed infrastructure, your team has no DevOps bandwidth, and cost isn't a primary concern.
Avoid when: you need hybrid search, complex metadata queries, or self-hosting for data residency requirements.
Cost reality: $70/month minimum for production use. Scales linearly with storage and queries. At 10M vectors + 1M queries/month: ~$400/month.
Qdrant: Best Performance at Any Scale
Qdrant is the highest-performance option with the most flexible filtering. Written in Rust, it's significantly faster than the alternatives on complex queries.
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ url: "http://localhost:6333" });
// Create collection with HNSW config
await client.createCollection("knowledge-base", {
vectors: { size: 1536, distance: "Cosine" },
hnsw_config: { m: 16, ef_construct: 200, full_scan_threshold: 10000 },
optimizers_config: { default_segment_number: 4 },
});
// Upsert with rich payload
await client.upsert("knowledge-base", {
points: [
{
id: 1,
vector: embedding,
payload: { text: "...", source: "docs", created_at: Date.now(), tags: ["api", "auth"] },
},
],
});
// Complex filtered search
const results = await client.search("knowledge-base", {
vector: queryEmbedding,
filter: {
must: [
{ key: "source", match: { value: "docs" } },
{ key: "created_at", range: { gte: Date.now() - 30 * 86400000 } },
],
should: [{ key: "tags", match: { any: ["api", "auth"] } }],
},
limit: 5,
with_payload: true,
});
Qdrant's payload filtering is significantly more expressive than Pinecone's — nested conditions, range filters, geo filters, and array membership all work natively.
Hybrid search (vector + keyword) built in:
const hybridResults = await client.query("knowledge-base", {
prefetch: [
{ query: queryEmbedding, using: "dense", limit: 20 },
{ query: { text: queryText }, using: "sparse", limit: 20 }, // BM25
],
query: { fusion: "rrf" }, // Reciprocal Rank Fusion
limit: 5,
});
Use Qdrant when: you need maximum performance, complex filtering, hybrid search, or self-hosting. Best for privacy-sensitive deployments.
Self-hosted cost: ~$20-50/month on a 4-core, 16GB RAM instance handles 10M vectors comfortably.
Weaviate: Best for Generative Search
Weaviate integrates tightly with LLM providers — you can configure it to call OpenAI/Anthropic directly and get generative search (RAG built into the DB layer).
import weaviate from "weaviate-client";
const client = await weaviate.connectToLocal();
// Define schema with vectorizer
await client.collections.create({
name: "Document",
vectorizers: weaviate.configure.vectors.text2VecOpenAI({
model: "text-embedding-3-small",
}),
generative: weaviate.configure.generative.anthropic({
model: "claude-sonnet-4-6",
}),
properties: [
{ name: "content", dataType: weaviate.configure.dataType.TEXT },
{ name: "source", dataType: weaviate.configure.dataType.TEXT },
],
});
// Insert — Weaviate auto-embeds
const collection = client.collections.get("Document");
await collection.data.insert({ content: "...", source: "docs" });
// Generative search — retrieves AND generates in one call
const result = await collection.generate.nearText(
["authentication error"],
{ groupedTask: "Explain how to fix authentication errors based on these docs" },
{ limit: 3 }
);
console.log(result.generated); // LLM-generated answer
Use Weaviate when: you want a tight integration between retrieval and generation, or you're building a document Q&A system where the DB layer handling generation simplifies your stack.
Avoid when: you need ACID guarantees, have an existing LLM pipeline, or find the tight LLM coupling inflexible.
pgvector: Best for Existing Postgres Users
If you already run Postgres, pgvector adds vector search without a new infrastructure component. Query vectors with SQL — join with other tables, use transactions, leverage existing ORMs.
-- Enable extension
CREATE EXTENSION vector;
-- Table with embedding column
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
source VARCHAR(100),
created_at TIMESTAMPTZ DEFAULT NOW(),
embedding vector(1536)
);
-- HNSW index for fast ANN search
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
import { drizzle } from "drizzle-orm/postgres-js";
import { sql } from "drizzle-orm";
// Search with metadata filter — plain SQL
const results = await db.execute(sql`
SELECT id, content, source,
1 - (embedding <=> ${JSON.stringify(queryEmbedding)}::vector) AS similarity
FROM documents
WHERE source = 'api-docs'
AND created_at > NOW() - INTERVAL '30 days'
ORDER BY embedding <=> ${JSON.stringify(queryEmbedding)}::vector
LIMIT 5
`);
Use pgvector when: you're already on Postgres, need ACID transactions with vector data, or want to join vector search with relational data. The ops cost is zero if Postgres is already running.
Limitations: slower than dedicated vector DBs at scale (>5M vectors), no native hybrid search, limited filter performance on large datasets.
How to Choose
Start here:
│
├── Already running Postgres?
│ └── YES → pgvector (zero extra infra)
│
├── Need managed service + simplicity?
│ └── YES → Pinecone
│
├── Need hybrid search / complex filters / high performance?
│ └── YES → Qdrant (self-hosted or Qdrant Cloud)
│
└── Need DB-layer RAG / tight LLM integration?
└── YES → Weaviate
At Shahriar Labs, we use Qdrant for production RAG workloads and pgvector for metadata-heavy applications where relational joins matter.
FAQ
How many vectors can each handle? All four handle 100M+ vectors at the infrastructure level. Pinecone pods have hard limits per index; Qdrant and Weaviate scale horizontally. pgvector degrades past ~10M vectors without careful index tuning.
Can I switch vector DBs later? Yes — your data is just (id, vector, metadata) tuples. Migration is straightforward but requires re-indexing. Choose carefully but don't over-engineer — start with the simplest option that works.
What embedding dimension should I use?
text-embedding-3-small → 1536. text-embedding-3-large → 3072. Higher dimensions = better quality + higher storage and query cost. For most RAG use cases, 1536 is sufficient.
Do I need a vector DB for <10,000 documents? No. At that scale, in-memory cosine similarity works fine. Use a simple array and numpy-style computation. Add a vector DB when you hit 50K+ documents or need filtering.
What about Chroma, Milvus, and Redis? Chroma: great for prototyping, not production-hardened. Milvus: enterprise-grade, complex to operate. Redis VSS: good if already running Redis, limited filtering. Qdrant/pgvector beat these for most teams in 2026.