Newsletter, guides
Choose a vector database: Chroma vs Qdrant vs pgvector
Chroma, Qdrant, Weaviate, pgvector, Pinecone and Vespa compared for RAG in 2026. A decision table, current code for each, and which one fits your stack.
You are building RAG and every tutorial picks a different vector database. Chroma, Qdrant, Weaviate, pgvector, Pinecone and Vespa all store embeddings and return the nearest ones. Picking the wrong one rarely breaks a demo. It shows up later, as a second database to run, a bill you did not plan for, or filters that make search slow.
A vector database stores embeddings and finds the closest ones to a query embedding, usually with an approximate index such as HNSW. The short answer: if you already run Postgres, start with pgvector. For a prototype, use Chroma. For a dedicated self-hosted server with heavy filtering, use Qdrant. If nobody on the team wants to run a database, use Pinecone or a managed tier. Weaviate fits when you want the database to embed and generate for you, and Vespa fits when search ranking is the product.
Key takeaways
- Pick by what you already run and who will operate it, not by benchmark charts. All six are fast enough for most RAG apps.
- pgvector keeps vectors next to your rows, so one SQL query can filter by tenant and rank by similarity. Use iterative index scans when filters are strict.
- Chroma runs in your process for prototypes, and also self-hosted or as Chroma Cloud when you outgrow that.
- Qdrant and Weaviate are dedicated servers with payload filters and hybrid search. Weaviate adds built-in vectorizers and generation.
- Pinecone is fully managed with usage-based billing on read units, write units and storage. Vespa is a full search engine for ranking at large scale.
What does a vector database do in RAG?
It does two jobs. On the write path it stores each chunk’s embedding and builds an index. On the read path it embeds the question, applies any metadata filter, and returns the top k chunks for the model to read.
The filter step is where the databases differ most in practice. Real RAG queries are rarely “nearest chunks in the whole corpus”. They are “nearest chunks for this tenant, this product, this date range”. How a database combines the filter with the vector index decides whether those queries stay fast and still return k results.
How do the six vector databases compare?
| Database | What it is | Best fit | Who runs it | License |
|---|---|---|---|---|
| Chroma | Embedded library, server or Chroma Cloud | Prototypes, local and small apps | You, or Chroma Cloud | Apache 2.0 |
| Qdrant | Dedicated vector search server | Filtered search at scale, self-hosted | You, or Qdrant Cloud | Apache 2.0 |
| Weaviate | Vector database with vectorizer and generative modules | Teams that want embedding and RAG inside the database | You, or Weaviate Cloud | BSD 3-Clause |
| pgvector | Postgres extension | Apps already on Postgres | Your Postgres host | PostgreSQL License |
| Pinecone | Managed serverless service | Production without running a database | Pinecone | Proprietary |
| Vespa | Search and ranking engine | Large-scale hybrid search with custom ranking | You, or Vespa Cloud | Apache 2.0 |
If you have not built the retrieval pipeline around the database yet, read choosing a RAG framework first. The framework decides how you call the database, and all three major frameworks support all six.
When is pgvector enough?
pgvector is enough when you already run Postgres and your corpus fits on one well-sized Postgres server. You add a vector column, build an HNSW index, and query with SQL. Your chunks sit next to the rows that own them, so access control is a WHERE clause and a join, not a sync job.
-- filename: schema.sql
-- description: pgvector table, HNSW index and a tenant-filtered similarity query.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE chunks (
id bigserial PRIMARY KEY,
tenant_id bigint NOT NULL,
content text NOT NULL,
embedding vector(1024) NOT NULL -- match your embedding model's dimensions
);
CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops);
CREATE INDEX ON chunks (tenant_id);
-- Keep scanning the index until enough rows pass the filter.
SET hnsw.iterative_scan = relaxed_order;
SELECT id, content
FROM chunks
WHERE tenant_id = $1
ORDER BY embedding <=> $2 -- cosine distance to the query embedding
LIMIT 10;
Two details matter. First, with an approximate index the filter runs after the index scan, so a strict filter can return fewer than 10 rows. Iterative index scans, added in pgvector 0.8.0, fix that by scanning more of the index until enough rows pass. Second, the vector type indexes up to 2,000 dimensions and halfvec up to 4,000. Pick an embedding size that fits, or use halfvec to halve the storage.
Keep pgvector patched. The 0.8.x line shipped several fixes for index build and vacuum bugs during 2026, including 0.8.7 on 1 October 2026.
When should you use Chroma?
Use Chroma when you want to start in minutes. It runs inside your Python process, in memory or saved to a folder, with no server. That makes it the default in notebooks, tests and local tools.
Chroma is no longer only a toy store. The same API runs as a self-hosted server or on Chroma Cloud, a managed serverless service, and its docs list dense, sparse and hybrid search plus full-text and regex search. Start embedded, and move to a server when more than one process needs the data. For a lower-level local option with no server at all, see the FAISS vector store guide.
Qdrant or Weaviate: which dedicated server?
Both are open-source servers you run in Docker or Kubernetes, or rent as a managed cloud. Both do payload filters and hybrid search. The difference is how much of the RAG pipeline they own.
Qdrant is a vector search engine and stays out of the rest. You bring your own embeddings. It is strong at filtered search: you index payload fields and pass filters inside the query, so the search and the filter run together. Use the Query API (query_points). Older tutorials use search and recreate_collection, which newer clients replaced.
# filename: qdrant_search.py
# description: Create a Qdrant collection, upsert points and run a filtered query.
from qdrant_client import QdrantClient
from qdrant_client.models import (
Distance, FieldCondition, Filter, MatchValue, PointStruct, VectorParams,
)
client = QdrantClient(url='http://localhost:6333')
client.create_collection(
collection_name='chunks',
vectors_config=VectorParams(size=1024, distance=Distance.COSINE),
)
client.create_payload_index('chunks', field_name='product', field_schema='keyword')
client.upsert(
collection_name='chunks',
points=[PointStruct(id=1, vector=embedding, payload={'product': 'xps-13'})],
)
hits = client.query_points(
collection_name='chunks',
query=query_embedding,
query_filter=Filter(must=[FieldCondition(key='product', match=MatchValue(value='xps-13'))]),
limit=10,
).points
Weaviate wants to own more of the pipeline. You configure a vectorizer on the collection and Weaviate embeds objects on insert and queries at search time. A generative module can pass results to an LLM and return the answer. In the current v4 Python client you set this with vector_config=Configure.Vectors... and get a collection with client.collections.use(...). Old tutorials that pass vectorizer_config strings are out of date.
Choose Qdrant when your app already embeds and you want a fast, narrow component. Choose Weaviate when you want fewer moving parts in your own code and accept the database’s way of doing RAG.
When is Pinecone worth paying for?
Pinecone is worth it when nobody on the team should be running a database. You create an index, get an API key, and Pinecone handles scaling, replication and upgrades.
Billing is usage-based. Pinecone charges read units per query (scaled by namespace size), write units per kilobyte upserted, and storage per gigabyte. Its docs list a free Starter plan, a $20 flat Builder plan, a Standard plan with a $50 monthly minimum, and Enterprise with a $500 minimum. Model your cost from those units before you commit: many small namespaces (one per tenant) keep each query’s read cost low.
The trade-off is lock-in and a separate system of record. Your chunks live in Pinecone, your users live in your database, and you keep them in sync. Qdrant, Weaviate and Chroma also sell managed clouds, so “managed” does not have to mean Pinecone.
When do you need Vespa?
You need Vespa when search ranking is the product, not a feature. Vespa combines BM25 text search, vector search, structured filters and multi-phase machine-learned ranking in one engine, and it scales to very large corpora. You describe documents and ranking in a schema and deploy it as an application.
That power costs setup time. For a support bot over 100,000 manuals, Vespa is more than you need. For a marketplace that ranks millions of items by relevance, freshness and business rules, it is built for exactly that. Yahoo spun Vespa out as an independent company in 2023, and Vespa Cloud is its managed service.
How should you choose your vector database?
Answer the questions in order. The first “yes” is usually your pick.
A solo developer building a prototype: Chroma. No server, no schema.
A team with Postgres adding RAG to existing data: pgvector. One database, SQL filters, joins with your users and permissions.
A product search over tens of millions of items with strict filters: Qdrant, with payload indexes on the filter fields.
A startup that must ship next week with no ops person: Pinecone, or the managed tier of Qdrant or Weaviate.
A company whose business is search quality: Vespa.
Whichever you pick, measure retrieval on your own questions. The database matters less than chunking, the embedding model and k. Tuning retriever top-k shows how to build that eval set.
What to do next
- Write down what you already run (Postgres or not) and who will operate the database.
- Use the decision flow above to pick one database. Do not run a bake-off of six.
- Load 1,000 of your real chunks and 50 real questions, with the filters your app needs.
- Measure recall at k and p95 latency with filters on. Strict filters are where databases differ.
- Price it at your expected volume: server size for self-hosted, read and write units for Pinecone.
- Hide the store behind one small retriever interface, so a later move is a one-file change.
Frequently asked questions
Is pgvector good enough for production RAG?
Yes, for most teams that already run Postgres. pgvector supports HNSW and IVFFlat indexes, cosine and inner product distance, and iterative index scans for filtered queries. It keeps vectors next to the rows that own them, so access control is plain SQL. Move to a dedicated server when the index no longer fits a single Postgres host or vector traffic starts to slow your main database.
What is the difference between Chroma and Qdrant?
Chroma starts embedded in your Python process with no server, which makes it the fastest way to prototype. It can also run as a server or on Chroma Cloud. Qdrant is a dedicated server from day one, built for high-throughput search with payload indexes and filters inside the query. Use Chroma to start and for local tools, and Qdrant when filtered search at scale is the main requirement.
Should I use Pinecone or a self-hosted vector database?
Use Pinecone when no one on the team should operate a database and usage-based billing fits your budget. Self-host Qdrant, Weaviate, Chroma or pgvector when you already run infrastructure, need data in your own cloud, or want cost tied to server size instead of read and write units. Qdrant, Weaviate and Chroma also offer managed clouds, so you can start managed and keep the option to self-host.
When should I use Weaviate instead of Qdrant?
Use Weaviate when you want the database to embed objects and call an LLM for you, so your code stays small. Use Qdrant when your app already produces embeddings and you want a focused search engine you control. Both support filters and hybrid search. The choice is about how much of the RAG pipeline you want inside the database.
Do I need a separate vector database at all?
Not always. If your corpus is small, an in-process index such as Chroma or FAISS is enough. If you run Postgres, pgvector avoids a second system. Add a dedicated vector database when scale, filtered search speed or isolation from your main database requires it, and measure first.
Sources
- pgvector README, pgvector, October 2026: HNSW and IVFFlat, dimension limits, filtering and
hnsw.iterative_scan. - pgvector changelog, pgvector, October 2026: iterative index scans in 0.8.0 and the 0.8.3 to 0.8.7 fixes.
- Qdrant quickstart, Qdrant, October 2026:
create_collection,upsertandquery_pointswith a payload filter. - Weaviate quickstart, Weaviate, October 2026:
vector_config=Configure.Vectorsandcollections.usein the v4 client. - Chroma introduction, Chroma, October 2026: local, self-hosted and Chroma Cloud, with dense, sparse, hybrid and full-text search.
- Understanding cost, Pinecone, October 2026: plan minimums and read unit, write unit and storage billing.
- Yahoo spins out Vespa, Yahoo, October 2023: Vespa as an independent company.
Build what you just read, with Param, live
You read the guide
- Free Live LabBuild a Second Brain with Claude CodeA second brain over your notes, docs and Linear that answers with sources and serves the same memory to any agent over MCP.Free seat
- ProWatch the video coursesDesign a Software Factory for Your Coding Agents, Build Your First Software Factory Execution Harness and each new course as the sessions are cut. The first lesson of each is free after you sign in.$149 a year
- WorkshopAI Agents in Production for EngineersA multi-agent system deployed with an identity per agent, permissions, guardrails, an LLM gateway, traces and evals, plus a checklist for your own agents.$497
- BuildcampAgentic AI Buildcamp for Engineers & PMsDesign, build and deploy a production agentic AI system in four weeks$997