DEV Community

Phil IPS
Phil IPS

Posted on

Vector Databases for AI Apps: Pinecone vs Weaviate vs Qdrant

Vector Databases for AI Apps: Pinecone vs Weaviate vs Qdrant

Complete comparison of managed and self-hosted vector databases for RAG and semantic search.

Introduction

Vector databases are essential for Retrieval-Augmented Generation (RAG), semantic search, and recommendation systems. This guide compares the top options for production AI applications.

What is a Vector Database?

Vector databases store and query high-dimensional embeddings (vectors) efficiently. Unlike traditional databases, they specialize in:

  • Similarity search (ANN - Approximate Nearest Neighbors)
  • Metadata filtering combined with vector search
  • Scalable to millions/billions of vectors

Quick Comparison

Feature Pinecone Weaviate Qdrant
Type Managed cloud Self-hosted / Cloud Self-hosted / Cloud
Free Tier 100k vectors Unlimited (self-hosted) 1M vectors (cloud)
Query Speed Excellent Very Good Excellent
Filtering Metadata GraphQL + SQL-like Payload filtering
Multi-tenancy Built-in Built-in Built-in
Ease of Setup Easiest Moderate Easy
Language Clients Python, JS, Go, Java Python, JS, Go, Java Python, JS, Rust, Go

Pinecone: Fully Managed Simplicity

import os
from pinecone import Pinecone, ServerlessSpec

pc = Pinecone(api_key=os.getenv("PINECONE_API_KEY"))

# Create index
index_name = "ai-docs"
if index_name not in pc.list_indexes().names():
    pc.create_index(
        name=index_name,
        dimension=1536,  # OpenAI ada-002
        metric="cosine",
        spec=ServerlessSpec(cloud="aws", region="us-east-1")
    )

index = pc.Index(index_name)

# Upsert vectors
vectors = [
    ("doc-1", [0.1]*1536, {"title": "AI Guide", "category": "tutorial"}),
    ("doc-2", [0.2]*1536, {"title": "ML Basics", "category": "intro"})
]
index.upsert(vectors=vectors)

# Query with metadata filter
results = index.query(
    vector=[0.15]*1536,
    top_k=5,
    filter={"category": "tutorial"},
    include_metadata=True
)
Enter fullscreen mode Exit fullscreen mode

Pros: Zero ops, auto-scaling, excellent SDK
Cons: Costly at scale, vendor lock-in

Weaviate: GraphQL + Hybrid Search

import weaviate
import os

client = weaviate.connect_to_weaviate_cloud(
    cluster_url=os.getenv("WEAVIATE_URL"),
    auth_credentials=weaviate.AuthApiKey(os.getenv("WEAVIATE_API_KEY"))
)

# Schema
client.collections.create(
    name="Document",
    properties=[
        weaviate.classes.config.Property(name="title", data_type=weaviate.classes.config.DataType.TEXT),
        weaviate.classes.config.Property(name="content", data_type=weaviate.classes.config.DataType.TEXT),
        weaviate.classes.config.Property(name="category", data_type=weaviate.classes.config.DataType.TEXT)
    ],
    vectorizer_config=weaviate.classes.config.Configure.Vectorizer.text2vec_openai()
)

# Insert
collection = client.collections.get("Document")
collection.data.insert({
    "title": "RAG Tutorial",
    "content": "Retrieval-Augmented Generation...",
    "category": "tutorial"
})

# Hybrid search (vector + keyword)
results = collection.query.hybrid(
    query="vector database tutorial",
    alpha=0.5,  # 0=keyword, 1=vector
    filters=weaviate.classes.query.Filter.by_property("category").equal("tutorial"),
    limit=5
)
Enter fullscreen mode Exit fullscreen mode

Pros: Hybrid search, GraphQL, modular architecture
Cons: More complex setup, resource intensive

Qdrant: High Performance, Rust-Powered

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter, FieldCondition, MatchValue
import os

client = QdrantClient(
    url=os.getenv("QDRANT_URL"),
    api_key=os.getenv("QDRANT_API_KEY")
)

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

# Upsert with payload
points = [
    PointStruct(id=1, vector=[0.1]*1536, payload={"title": "AI Guide", "category": "tutorial"}),
    PointStruct(id=2, vector=[0.2]*1536, payload={"title": "ML Basics", "category": "intro"})
]
client.upsert(collection_name="documents", points=points)

# Query with payload filtering
results = client.query_points(
    collection_name="documents",
    query=[0.15]*1536,
    query_filter=Filter(
        must=[FieldCondition(key="category", match=MatchValue(value="tutorial"))]
    ),
    limit=5,
    with_payload=True
)
Enter fullscreen mode Exit fullscreen mode

Pros: Fastest, binary quantization, rich filtering, self-hostable
Cons: Younger ecosystem, fewer integrations

Self-Hosted Quick Start

Weaviate (Docker)

docker run -d -p 8080:8080 \
  -e QUERY_DEFAULTS_LIMIT=25 \
  -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
  -e DEFAULT_VECTORIZER_MODULE=text2vec-openai \
  -e ENABLE_MODULES=text2vec-openai \
  cr.weaviate.io/semitechnologies/weaviate:1.25.0
Enter fullscreen mode Exit fullscreen mode

Qdrant (Docker)

docker run -d -p 6333:6333 -p 6334:6334 \
  -v $(pwd)/qdrant_storage:/qdrant/storage \
  qdrant/qdrant
Enter fullscreen mode Exit fullscreen mode

RAG Pipeline Example (Any DB)

import os
from openai import OpenAI

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# or use OpenRouter: base_url="https://openrouter.ai/api/v1"

def get_embedding(text: str) -> list:
    response = client.embeddings.create(
        model="text-embedding-3-small",  # 1536 dims
        input=text
    )
    return response.data[0].embedding

def rag_query(question: str, vector_db, collection: str = "documents") -> str:
    # 1. Embed question
    query_vector = get_embedding(question)

    # 2. Search vector DB (adapt to your DB)
    results = vector_db.query(vector=query_vector, top_k=3)

    # 3. Build context
    context = "\n\n".join([r.metadata.get("content", "") for r in results])

    # 4. Generate answer
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "Answer using only the provided context."},
            {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {question}"}
        ],
        temperature=0.1
    )
    return response.choices[0].message.content
Enter fullscreen mode Exit fullscreen mode

Cost Comparison (1M vectors, 1536 dims)

Provider Monthly Cost Notes
Pinecone (starter) ~$70 Managed, auto-scales
Weaviate Cloud ~$50 Managed, includes vectorizer
Qdrant Cloud ~$30 Best price/performance
Self-hosted (VPS) $10-20 4GB RAM VPS, full control

Recommendation by Scenario

Scenario Choose
Zero DevOps, quick start Pinecone
Hybrid search (keyword + vector) Weaviate
Maximum performance, cost-sensitive Qdrant
Full control, on-premise Qdrant / Weaviate self-hosted
GraphQL-first stack Weaviate
Rust/Go backend Qdrant

Free Tier Limits

Provider Vectors Dimensions Requests
Pinecone 100,000 Up to 1536 Unlimited
Weaviate Cloud 10M objects Any 1M/month
Qdrant Cloud 1,000,000 Any Generous
Self-hosted Unlimited Unlimited Hardware limit

Conclusion

  • Start with Pinecone for fastest time-to-production
  • Switch to Qdrant when scaling beyond free tier or need max performance
  • Choose Weaviate if hybrid search (keyword + vector) is critical
  • Self-host Qdrant for lowest cost at scale

All three handle production RAG workloads well. The choice depends on your team's expertise, budget, and specific search requirements.


Part of the Vector Database series on Dev.to

Top comments (0)