Vector Database Comparison for RAG

RAGVector DatabaseComparisonTutorial

Compare top vector databases for RAG systems: Chroma, Qdrant, Pinecone, Weaviate, Milvus, and more.

Vector Database Comparison for RAG

Overview

Choosing the right vector database is critical for building production RAG systems. This guide compares the top vector databases across performance, features, and use cases.

Comparison Matrix

DatabaseTypeQuery SpeedScaleCostBest For
ChromaEmbeddedFastMediumFreePrototyping, small apps
QdrantServerVery FastLargeFree/PaidProduction RAG
PineconeManagedVery FastLargePaidEnterprise, no infra
WeaviateServerFastLargeFree/PaidHybrid search
MilvusServerFastVery LargeFree/PaidMassive scale
ElasticsearchSearchMediumLargeFree/PaidFull-text + vectors
pgvectorExtensionMediumMediumFreePostgreSQL users

Deep Dive: Each Database

Chroma

Overview: Lightweight, embedded vector database ideal for development and small deployments.

# Installation
pip install chromadb

# Quick start
import chromadb
client = chromadb.Client()

# Create collection
collection = client.create_collection("my_docs")

# Add documents
collection.add(
    documents=["Document 1", "Document 2"],
    embeddings=[[0.1, 0.2, ...], [0.3, 0.4, ...]],
    ids=["id1", "id2"]
)

# Query
results = collection.query(
    query_embeddings=[[0.1, 0.2, ...]],
    n_results=5
)

Pros:

  • ✅ Zero configuration
  • ✅ No server required
  • ✅ Python/JS SDKs
  • ✅ Active development

Cons:

  • ❌ Limited scalability
  • ❌ No built-in auth
  • ❌ Single-node only

Best for: Prototyping, small applications, local development


Qdrant

Overview: High-performance vector database with advanced filtering and hybrid search.

# Installation
pip install qdrant-client

# Quick start
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct

client = QdrantClient(url="http://localhost:6333")

# Create collection
client.create_collection(
    collection_name="my_docs",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
)

# Upsert points
client.upsert(
    collection_name="my_docs",
    points=[
        PointStruct(
            id=1,
            vector=[0.1, 0.2, ...],
            payload={"title": "Document 1", "category": "tech"}
        )
    ]
)

# Query with filtering
results = client.search(
    collection_name="my_docs",
    query_vector=[0.1, 0.2, ...],
    query_filter=models.Filter(
        must=[models.FieldCondition(key="category", match=models.MatchValue(value="tech"))]
    ),
    limit=5
)

Pros:

  • ✅ Excellent performance
  • ✅ Rich filtering
  • ✅ Hybrid search support
  • ✅ REST and gRPC APIs
  • ✅ Cloud and self-hosted

Cons:

  • ❌ More complex setup
  • ❌ Rust-based (limited language support)

Best for: Production RAG, applications needing filtering


Pinecone

Overview: Fully managed vector database with zero infrastructure management.

# Installation
pip install pinecone

# Quick start
from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")

# Create index
pc.create_index(
    name="my-index",
    dimension=1536,
    metric="cosine",
    spec={"serverless": {"cloud": "aws", "region": "us-east-1"}}
)

# Connect to index
index = pc.Index("my-index")

# Upsert
index.upsert(
    vectors=[
        ("id1", [0.1, 0.2, ...], {"title": "Document 1"})
    ]
)

# Query
results = index.query(
    vector=[0.1, 0.2, ...],
    top_k=5,
    include_metadata=True
)

Pros:

  • ✅ Zero infrastructure
  • ✅ Auto-scaling
  • ✅ High availability
  • ✅ Simple API
  • ✅ Good documentation

Cons:

  • ❌ Paid service
  • ❌ Vendor lock-in
  • ❌ Limited customization

Best for: Enterprise applications, teams without infra resources


Weaviate

Overview: Modular vector database with built-in ML models and hybrid search.

# Installation
pip install weaviate-client

# Quick start
import weaviate

client = weaviate.Client("http://localhost:8080")

# Create schema
client.schema.create_class({
    "class": "Article",
    "properties": [
        {"name": "title", "dataType": ["string"]},
        {"name": "content", "dataType": ["text"]}
    ],
    "vectorizer": "text2vec-openai"
})

# Add object
client.data_object.create(
    data_object={"title": "Article 1", "content": "Content..."},
    class_name="Article"
)

# Hybrid search
results = client.query.get("Article", ["title", "content"]).with_hybrid(
    query="machine learning",
    alpha=0.5
).do()

Pros:

  • ✅ Built-in vectorizers
  • ✅ Hybrid search (BM25 + vectors)
  • ✅ GraphQL API
  • ✅ Multi-tenancy support

Cons:

  • ❌ More complex schema
  • ❌ Slower than dedicated vector DBs

Best for: Applications needing hybrid search, multi-tenancy


Milvus

Overview: Scalable vector database designed for massive-scale applications.

# Installation
pip install pymilvus

# Quick start
from pymilvus import connections, FieldSchema, CollectionSchema, Collection, DataType

# Connect
connections.connect("default", host="localhost", port="19530")

# Define schema
fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
    FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=1536),
    FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=100)
]
schema = CollectionSchema(fields)

# Create collection
collection = Collection("my_docs", schema)

# Insert
collection.insert([
    [1, 2],
    [[0.1, ...], [0.3, ...]],
    ["Doc 1", "Doc 2"]
])

# Search
results = collection.search(
    data=[[0.1, 0.2, ...]],
    anns_field="vector",
    param={"metric_type": "COSINE", "params": {"nprobe": 10}},
    limit=5
)

Pros:

  • ✅ Massive scale support
  • ✅ Horizontal scaling
  • ✅ Multiple index types
  • ✅ Cloud-native architecture

Cons:

  • ❌ Complex deployment
  • ❌ Steeper learning curve
  • ❌ More infrastructure overhead

Best for: Large-scale production, high-throughput applications


pgvector

Overview: PostgreSQL extension for vector similarity search.

# Installation
# PostgreSQL with pgvector extension enabled

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from pgvector.sqlalchemy import Vector

Base = declarative_base()

class Document(Base):
    __tablename__ = "documents"
    id = Column(Integer, primary_key=True)
    title = Column(String)
    embedding = Column(Vector(1536))

# Create tables
engine = create_engine("postgresql://user:pass@localhost/dbname")
Base.metadata.create_all(engine)

# Query
from sqlalchemy.orm import Session
session = Session(engine)

results = session.query(Document).order_by(
    Document.embedding.cosine_distance([0.1, 0.2, ...])
).limit(5).all()

Pros:

  • ✅ Uses existing PostgreSQL infra
  • ✅ ACID compliance
  • ✅ Rich SQL queries
  • ✅ No new infrastructure

Cons:

  • ❌ Slower than dedicated vector DBs
  • ❌ Limited vector-specific features
  • ❌ Scale limitations

Best for: Teams already using PostgreSQL, moderate scale


Elasticsearch

Overview: Search engine with vector capabilities for hybrid search.

# Installation
pip install elasticsearch

# Quick start
from elasticsearch import Elasticsearch

es = Elasticsearch("http://localhost:9200")

# Create index with dense vector field
es.indices.create(index="my_docs", body={
    "mappings": {
        "properties": {
            "title": {"type": "text"},
            "content": {"type": "text"},
            "embedding": {"type": "dense_vector", "dims": 1536}
        }
    }
})

# Index document
es.index(
    index="my_docs",
    body={
        "title": "Document 1",
        "content": "Content...",
        "embedding": [0.1, 0.2, ...]
    }
)

# KNN search
results = es.search(
    index="my_docs",
    body={
        "knn": {
            "field": "embedding",
            "query_vector": [0.1, 0.2, ...],
            "k": 5,
            "num_candidates": 100
        }
    }
)

Pros:

  • ✅ Full-text + vector search
  • ✅ Mature ecosystem
  • ✅ Built-in analytics
  • ✅ Horizontal scaling

Cons:

  • ❌ Higher resource usage
  • ❌ Complex configuration
  • ❌ Vector search less optimized

Best for: Applications needing full-text + vector search


Performance Benchmarks

Query Latency (ms) - 1M vectors, 1536-dim

DatabaseP50P95P99
Qdrant2.14.58.2
Pinecone2.35.19.0
Milvus2.55.510.2
Weaviate3.26.812.5
Chroma5.012.025.0
pgvector8.018.035.0

Throughput (queries/sec) - Single node

DatabaseQPS
Qdrant2,500
Pinecone2,000
Milvus3,000
Weaviate1,500
Chroma500
pgvector200

Decision Framework

Choose Based on Your Needs

For Prototyping:

Chroma → Fast setup, no infra, great for learning

For Production (Medium Scale):

Qdrant → Best performance/features balance

For Production (Enterprise):

Pinecone → Zero infra, managed service
Milvus → Maximum scale, self-hosted

For Hybrid Search:

Weaviate → Built-in hybrid search
Elasticsearch → Full-text + vectors

For PostgreSQL Users:

pgvector → Leverage existing infra

Migration Guide

From Chroma to Qdrant

# Chroma code
import chromadb
chroma_client = chromadb.Client()
collection = chroma_client.create_collection("docs")

# Migrate to Qdrant
from qdrant_client import QdrantClient
qdrant = QdrantClient(url="http://localhost:6333")
qdrant.create_collection("docs", vectors_config=VectorParams(size=1536, distance=Distance.COSINE))

# Export from Chroma
data = collection.get()

# Import to Qdrant
from qdrant_client.models import PointStruct
points = [
    PointStruct(
        id=id,
        vector=vector,
        payload={"document": doc}
    )
    for id, vector, doc in zip(data["ids"], data["embeddings"], data["documents"])
]
qdrant.upsert(collection_name="docs", points=points)

Resources


Last updated: May 2026