Vector Databases Compared: Pinecone vs Weaviate vs Qdrant vs Chroma vs pgvector 2025
A comprehensive comparison of the top vector databases in 2025. Learn how Pinecone, Weaviate, Qdrant, Chroma, and pgvector differ in performance, pricing, and use cases for RAG and semantic search.
Vector databases have become the backbone of modern AI applications. Whether you’re building a RAG (Retrieval-Augmented Generation) pipeline, a semantic search engine, or a recommendation system, your choice of vector store determines your performance ceiling and your operational costs.
This guide cuts through the marketing and gives you a real comparison of the five most commonly used vector databases in 2025: Pinecone, Weaviate, Qdrant, Chroma, and pgvector.
What Is a Vector Database?
A vector database stores high-dimensional numerical representations of data—called embeddings—and lets you search them by semantic similarity rather than exact match. When you embed a sentence with a model like OpenAI’s text-embedding-3-small, you get a vector like [0.23, -0.81, 0.44, ...] with 1536 dimensions. A vector database stores millions of these and finds the closest ones to a query vector in milliseconds.
Key operations:
- Insert: Store a vector (with optional metadata/payload)
- Query (ANN search): Find the K nearest neighbors to a query vector
- Filter: Narrow results using metadata conditions
- Delete/Update: Remove or refresh vectors
Quick Comparison Table
| Feature | Pinecone | Weaviate | Qdrant | Chroma | pgvector |
|---|---|---|---|---|---|
| Type | Managed cloud | Open-source / Cloud | Open-source / Cloud | Open-source | PostgreSQL extension |
| Self-hosted | ❌ | ✅ | ✅ | ✅ | ✅ |
| Free tier | ✅ (1 index) | ✅ | ✅ | ✅ | ✅ (PostgreSQL) |
| Indexing | HNSW | HNSW | HNSW | HNSW | HNSW / IVFFlat |
| Filtering | Metadata filters | GraphQL / filters | Payload filters | Metadata filters | SQL WHERE |
| Multi-tenancy | Namespaces | Multi-tenancy | Collections | Collections | Schemas/Tables |
| Hybrid search | ✅ (sparse+dense) | ✅ | ✅ | ❌ | Partial |
| Best for | Production, scale | Complex data models | Performance | Local dev, prototyping | Existing Postgres stack |
1. Pinecone
The managed, zero-ops option.
Pinecone is the most widely used vector database in production. It’s fully managed, meaning you never touch infrastructure. You create an index, insert vectors, and query—that’s it.
Architecture
Pinecone uses a serverless architecture (since 2024). Vectors are stored in its proprietary storage layer with HNSW-like indexing. Namespaces let you partition a single index for multi-tenancy.
Python SDK Example
from pinecone import Pinecone
pc = Pinecone(api_key="your-api-key")
index = pc.Index("my-index")
# Upsert vectors
index.upsert(vectors=[
{"id": "doc1", "values": [0.1, 0.2, 0.3, ...], "metadata": {"source": "blog", "year": 2025}},
{"id": "doc2", "values": [0.4, 0.5, 0.6, ...], "metadata": {"source": "docs", "year": 2024}},
])
# Query with metadata filter
results = index.query(
vector=[0.1, 0.2, 0.3, ...],
top_k=5,
filter={"year": {"$gte": 2025}},
include_metadata=True
)
Hybrid Search (Sparse + Dense)
Pinecone supports hybrid search combining dense vectors (semantic) with sparse vectors (BM25-style keyword):
index.query(
vector=[0.1, 0.2, ...], # dense
sparse_vector={"indices": [10, 45, 99], "values": [0.5, 0.3, 0.8]}, # sparse
top_k=10,
include_metadata=True
)
Pricing
- Free: 1 serverless index, ~100k vectors
- Standard: $0.033 per GB/month (storage) + $4/million read units
- Enterprise: Custom pricing
When to Use Pinecone
- You want zero DevOps burden
- Production workloads requiring high availability
- Team without vector DB expertise
- Need reliable SLAs
When to Avoid Pinecone
- Tight budget (costs scale quickly)
- Need full data control / on-prem
- Complex data models (Pinecone is vectors-only)
2. Weaviate
The knowledge graph vector database.
Weaviate uniquely combines vector search with a schema-based data model. Each object has a class (like a table), properties, and an embedding—making it more like a vector-native database than a pure vector store.
Architecture
Weaviate uses HNSW for vector indexing and supports multiple vectorizer modules (OpenAI, Cohere, HuggingFace) that can auto-embed your data on insert. Its GraphQL API gives you flexible querying.
Python SDK Example
import weaviate
client = weaviate.Client("http://localhost:8080")
# Define schema
schema = {
"class": "Article",
"vectorizer": "text2vec-openai",
"properties": [
{"name": "title", "dataType": ["text"]},
{"name": "content", "dataType": ["text"]},
{"name": "year", "dataType": ["int"]},
]
}
client.schema.create_class(schema)
# Add object (auto-vectorized)
client.data_object.create(
data_object={"title": "Vector DBs in 2025", "content": "...", "year": 2025},
class_name="Article"
)
# Semantic search with filter
result = (
client.query
.get("Article", ["title", "content"])
.with_near_text({"concepts": ["vector database comparison"]})
.with_where({"path": ["year"], "operator": "GreaterThan", "valueInt": 2024})
.with_limit(5)
.do()
)
Auto-Vectorization
Weaviate’s killer feature: define a vectorizer module and objects are embedded automatically on insert. No separate embedding step needed.
Hybrid Search
result = (
client.query
.get("Article", ["title"])
.with_hybrid(query="vector database", alpha=0.5) # 0=BM25, 1=vector
.with_limit(5)
.do()
)
Pricing
- Open-source: Free (self-host)
- Cloud: Free sandbox, then ~$25/month starter
- Enterprise: Custom
When to Use Weaviate
- Complex data models with relationships
- Want auto-vectorization (skip separate embedding step)
- Knowledge graph use cases
- Need GraphQL flexibility
When to Avoid Weaviate
- Simple use cases (overkill)
- Latency-critical applications (GraphQL overhead)
- Very large scale (Qdrant often outperforms)
3. Qdrant
The performance-first open-source option.
Qdrant (written in Rust) is the fastest self-hosted vector database in most benchmarks. It’s built for high-throughput production workloads while remaining easy to run locally via Docker.
Architecture
Qdrant organizes data into collections (like tables). Each point has a vector, optional named vectors (multi-vector), and a payload (JSON metadata). HNSW indexing with configurable m and ef_construct parameters.
Python SDK Example
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter, FieldCondition, Range
client = QdrantClient("localhost", port=6333)
# Create collection
client.create_collection(
collection_name="documents",
vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
)
# Insert points
client.upsert(
collection_name="documents",
points=[
PointStruct(id=1, vector=[0.1, 0.2, ...], payload={"source": "blog", "year": 2025}),
PointStruct(id=2, vector=[0.4, 0.5, ...], payload={"source": "docs", "year": 2024}),
]
)
# Search with filter
results = client.search(
collection_name="documents",
query_vector=[0.1, 0.2, ...],
query_filter=Filter(
must=[FieldCondition(key="year", range=Range(gte=2025))]
),
limit=5
)
Named Vectors (Multi-Vector)
Qdrant supports storing multiple vectors per point—useful for multi-modal or late-interaction models:
client.create_collection(
collection_name="multimodal",
vectors_config={
"text": VectorParams(size=1536, distance=Distance.COSINE),
"image": VectorParams(size=512, distance=Distance.EUCLID),
}
)
Sparse + Dense Hybrid Search
from qdrant_client.models import SparseVector, NamedSparseVector
client.search_batch(
collection_name="documents",
requests=[
SearchRequest(
vector=NamedVector(name="dense", vector=[0.1, 0.2, ...]),
with_payload=True,
limit=5,
),
SearchRequest(
vector=NamedSparseVector(name="sparse", vector=SparseVector(indices=[10, 45], values=[0.5, 0.3])),
limit=5,
),
]
)
Pricing
- Open-source: Free (Docker / binary)
- Qdrant Cloud: Free 1GB cluster, then ~$25/month
- Enterprise: Custom
When to Use Qdrant
- Maximum performance requirements
- High-volume production (millions of vectors)
- Need fine-grained HNSW tuning
- Want Rust-level reliability + memory efficiency
When to Avoid Qdrant
- Need auto-vectorization (must embed separately)
- Team unfamiliar with ops (though Docker makes it easy)
- Need PostgreSQL-native (use pgvector instead)
4. Chroma
The developer-first local database.
Chroma is designed for rapid prototyping and local development. It runs in-memory or with SQLite persistence, has an extremely simple API, and integrates directly with LangChain and LlamaIndex out of the box.
Architecture
Chroma uses HNSW (via hnswlib) for approximate nearest neighbor search. It supports in-memory mode (ephemeral) and persistent mode (SQLite + local files). Client/server mode available for shared access.
Python SDK Example
import chromadb
from chromadb.utils import embedding_functions
# In-memory client
client = chromadb.Client()
# Or persistent
client = chromadb.PersistentClient(path="./chroma_db")
# Create collection with embedding function
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
api_key="your-key",
model_name="text-embedding-3-small"
)
collection = client.create_collection(
name="documents",
embedding_function=openai_ef
)
# Add documents (auto-embedded)
collection.add(
documents=["Vector DBs are fast", "Embeddings encode meaning"],
metadatas=[{"source": "blog"}, {"source": "docs"}],
ids=["doc1", "doc2"]
)
# Query
results = collection.query(
query_texts=["how do vector databases work?"],
n_results=3,
where={"source": "blog"} # metadata filter
)
LangChain Integration
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
vectorstore = Chroma(
collection_name="my_docs",
embedding_function=OpenAIEmbeddings(),
persist_directory="./chroma_db"
)
# Add and retrieve
vectorstore.add_texts(["text1", "text2"], metadatas=[{"id": 1}, {"id": 2}])
docs = vectorstore.similarity_search("query text", k=3)
Limitations
- No hybrid search: Chroma lacks sparse vector / BM25 support
- Single-node only: No horizontal scaling
- Basic filtering: Metadata filters but no complex conditions
- Performance: Not suitable for millions of vectors in production
Pricing
- Open-source: Free
- Chroma Cloud: Available (beta)
When to Use Chroma
- Prototyping and local development
- Jupyter notebooks and experiments
- Simple RAG pipelines
- Teams new to vector search
When to Avoid Chroma
- Production with high query volume
- Need hybrid search
- Millions of vectors
- Multi-node requirements
5. pgvector
The Postgres-native option.
pgvector is a PostgreSQL extension that adds vector storage and similarity search to your existing database. If you’re already on Postgres, it’s the lowest-friction path to vector search.
Architecture
pgvector adds a vector data type and two index types:
- HNSW: Best for query performance (added in pgvector 0.5.0)
- IVFFlat: Best for insert performance + lower memory
You write regular SQL—no new client library needed.
SQL Examples
-- Enable extension
CREATE EXTENSION IF NOT EXISTS vector;
-- Create table with vector column
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536),
source TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- Create HNSW index
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- Insert with embedding
INSERT INTO documents (content, embedding, source)
VALUES ('Vector search with Postgres', '[0.1, 0.2, ...]'::vector, 'blog');
-- Cosine similarity search
SELECT id, content, source,
1 - (embedding <=> '[0.1, 0.2, ...]'::vector) AS similarity
FROM documents
WHERE source = 'blog'
ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector
LIMIT 5;
Operators:
<=>— cosine distance<->— L2 (Euclidean) distance<#>— negative inner product (dot product)
Python with psycopg2
import psycopg2
import numpy as np
conn = psycopg2.connect("postgresql://user:pass@localhost/mydb")
cur = conn.cursor()
embedding = np.array([0.1, 0.2, 0.3, ...])
cur.execute(
"""
SELECT id, content, 1 - (embedding <=> %s::vector) AS similarity
FROM documents
WHERE source = %s
ORDER BY embedding <=> %s::vector
LIMIT 5
""",
(embedding.tolist(), 'blog', embedding.tolist())
)
results = cur.fetchall()
With SQLAlchemy + pgvector
from sqlalchemy import Column, Integer, Text
from sqlalchemy.orm import declarative_base
from pgvector.sqlalchemy import Vector
Base = declarative_base()
class Document(Base):
__tablename__ = "documents"
id = Column(Integer, primary_key=True)
content = Column(Text)
embedding = Column(Vector(1536))
# Query
from sqlalchemy import select
stmt = (
select(Document)
.order_by(Document.embedding.cosine_distance(query_vector))
.limit(5)
)
Limitations
- Scale: Struggles above ~1M vectors (single node)
- No hybrid search: Pure vector search only (combine with
tsvectormanually) - Memory: HNSW index lives in RAM—large datasets need large instances
- Managed: Supabase, Neon, and RDS all support pgvector
Pricing
- Open-source: Free (add to any Postgres)
- Supabase: Free tier with pgvector
- Neon: Free tier with pgvector
When to Use pgvector
- Already running PostgreSQL
- Want ACID transactions + vector search in one DB
- Moderate scale (< 1M vectors)
- Team knows SQL
When to Avoid pgvector
- Large-scale vector workloads (> 5M vectors)
- Need advanced filtering + vector together at scale
- Performance is the primary concern
Similarity Search Algorithms: HNSW vs IVFFlat
Both Qdrant and pgvector expose index configuration. Understanding the tradeoff helps:
HNSW (Hierarchical Navigable Small World)
- How it works: Builds a multi-layer graph. Queries traverse from high layers (coarse) to low layers (fine).
- Pros: Fast queries, no training step, good recall
- Cons: High memory usage, slow build time for large datasets
- Best for: Query-heavy workloads where you can afford memory
Key params:
m: Max connections per node (higher = better recall, more memory). Default 16.ef_construction: Build-time search width (higher = better index quality, slower build). Default 64.ef(query): Runtime search width (higher = better recall, slower query).
IVFFlat (Inverted File with Flat Quantization)
- How it works: Clusters vectors into
lists(Voronoi cells). Query searches the nearestprobesclusters. - Pros: Lower memory, faster build
- Cons: Lower recall than HNSW, requires training (needs data before indexing)
- Best for: Write-heavy workloads, memory-constrained environments
Key params:
lists: Number of clusters. Rule of thumb:sqrt(n_vectors).probes: Clusters to search at query time. Higher = better recall, slower.
Distance Metrics
| Metric | Formula | Best For |
|---|---|---|
| Cosine | 1 - (a·b / |a||b|) | Text embeddings (normalized) |
| Dot Product | -a·b | When vectors are already normalized |
| Euclidean (L2) | sqrt(Σ(aᵢ-bᵢ)²) | Image embeddings, spatial data |
Most text embedding models (OpenAI, Cohere, sentence-transformers) output normalized vectors, making cosine and dot product equivalent.
RAG Pipeline: Which DB to Use?
A typical RAG pipeline:
User query → Embed query → Vector search → Retrieve top-K docs → LLM generates answer
For prototyping: Chroma — simplest setup, works in a notebook.
For production (< 1M docs): Qdrant or pgvector — Qdrant for pure vector performance, pgvector if you’re on Postgres.
For production (> 1M docs, no ops): Pinecone — managed, scales automatically.
For complex schemas + auto-embedding: Weaviate — handles multi-class data and vectorizes on ingest.
# Example RAG with Qdrant + LangChain
from langchain_qdrant import QdrantVectorStore
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.chains import RetrievalQA
vectorstore = QdrantVectorStore.from_existing_collection(
url="http://localhost:6333",
collection_name="documents",
embedding=OpenAIEmbeddings()
)
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4o"),
retriever=vectorstore.as_retriever(search_kwargs={"k": 5}),
)
answer = qa_chain.invoke({"query": "What are the best vector databases in 2025?"})
Semantic Search: Quick Benchmark Reference
Based on public benchmarks (ANN-benchmarks, Qdrant’s own tests at 1M vectors, 768-dim):
| Database | Recall@10 | QPS (single node) | Notes |
|---|---|---|---|
| Qdrant | ~0.97 | ~2,000+ | HNSW, Rust core |
| Weaviate | ~0.96 | ~1,500+ | HNSW, Go core |
| Pinecone | ~0.97 | Managed (scales) | Cloud-only |
| pgvector | ~0.95 | ~500-1,000 | Depends on Postgres config |
| Chroma | ~0.94 | ~200-500 | Single node, Python |
These are approximate. Benchmark with your own data and hardware.
Recommendation Matrix
| Your Situation | Recommended Choice |
|---|---|
| Just prototyping / learning | Chroma |
| Production, no DevOps team | Pinecone |
| Production, want control, high scale | Qdrant |
| Already on PostgreSQL, < 1M docs | pgvector |
| Complex data model + auto-embedding | Weaviate |
| Multi-modal (text + image vectors) | Qdrant (named vectors) |
| Need ACID + vector in same DB | pgvector |
| Hybrid search (sparse + dense) | Pinecone or Qdrant |
Getting Started: 5-Minute Setup for Each
Chroma (local):
pip install chromadb
python -c "import chromadb; c = chromadb.Client(); print('Ready')"
Qdrant (Docker):
docker run -p 6333:6333 qdrant/qdrant
pip install qdrant-client
Weaviate (Docker):
docker run -p 8080:8080 -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true semitechnologies/weaviate:latest
pip install weaviate-client
pgvector (Docker):
docker run -e POSTGRES_PASSWORD=pass -p 5432:5432 ankane/pgvector
psql -h localhost -U postgres -c "CREATE EXTENSION vector;"
Pinecone (cloud):
pip install pinecone
# Sign up at pinecone.io, get API key
Final Thoughts
There’s no universally best vector database—the right choice depends on your scale, team, and infrastructure. Here’s the short version:
- Chroma: Fastest path from zero to working RAG demo
- Qdrant: Best self-hosted option for production
- Weaviate: Best when your data has complex structure
- pgvector: Best when you’re already on Postgres
- Pinecone: Best when you want zero infrastructure concerns
For deeper tooling, explore the database tools on DevPlaybook—including schema designers, query builders, and connection testers that work with any of these backends.
The vector database space is still evolving rapidly. Capabilities that differentiated databases in 2023 (like hybrid search) are now table stakes. Evaluate based on your current bottleneck: is it dev velocity, query latency, scale, or cost?
50 CLI Commands That Save Hours Every Week
The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.
- Git mastery (10 cmds)
- File & search wizardry
- Docker & DevOps tricks
- Process & network tools
- Productivity boosters
- macOS & Linux install guide
No spam. 1 email/week max. Unsubscribe anytime.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links — we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.