[SL_CORE]
< CD ..||7 min read

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-database][rag][infrastructure][embeddings]

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.