Skip to main content
← All Articles · · 14 min read

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-databasepineconeweaviateqdrantchromapgvectormachine-learningairagsemantic-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

FeaturePineconeWeaviateQdrantChromapgvector
TypeManaged cloudOpen-source / CloudOpen-source / CloudOpen-sourcePostgreSQL extension
Self-hosted❌✅✅✅✅
Free tier✅ (1 index)✅✅✅✅ (PostgreSQL)
IndexingHNSWHNSWHNSWHNSWHNSW / IVFFlat
FilteringMetadata filtersGraphQL / filtersPayload filtersMetadata filtersSQL WHERE
Multi-tenancyNamespacesMulti-tenancyCollectionsCollectionsSchemas/Tables
Hybrid search✅ (sparse+dense)✅✅❌Partial
Best forProduction, scaleComplex data modelsPerformanceLocal dev, prototypingExisting 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.

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),
    }
)
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 tsvector manually)
  • 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 nearest probes clusters.
  • 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

MetricFormulaBest For
Cosine1 - (a·b / |a||b|)Text embeddings (normalized)
Dot Product-a·bWhen 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):

DatabaseRecall@10QPS (single node)Notes
Qdrant~0.97~2,000+HNSW, Rust core
Weaviate~0.96~1,500+HNSW, Go core
Pinecone~0.97Managed (scales)Cloud-only
pgvector~0.95~500-1,000Depends on Postgres config
Chroma~0.94~200-500Single node, Python

These are approximate. Benchmark with your own data and hardware.


Recommendation Matrix

Your SituationRecommended Choice
Just prototyping / learningChroma
Production, no DevOps teamPinecone
Production, want control, high scaleQdrant
Already on PostgreSQL, < 1M docspgvector
Complex data model + auto-embeddingWeaviate
Multi-modal (text + image vectors)Qdrant (named vectors)
Need ACID + vector in same DBpgvector
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?

Free Download

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.