
Skip the Server: ChromaDB Gives You a Full Vector Database in Five Lines of Python
Chris Harper
3 min read
Aug 2, 2026 · 12:08 UTC
ChromaDB is the fastest path to a working vector database: pip install chromadb, five lines of Python, and you're doing semantic search — no Docker, no server, no cloud account.
What you'll be able to do after this:
- Add vector search to any Python project without provisioning infrastructure
- Query a collection by meaning — and filter by metadata at the same time
- Persist collections to disk and reload them across sessions with a single constructor change
Resource: Mastering ChromaDB: Step-by-Step Python Guide (YouTube, July 2026)
Why ChromaDB first?
pgvector (which you may have seen here) requires PostgreSQL. FAISS requires manual index management and serialization. ChromaDB runs as an embedded Python library — it creates an SQLite-backed store on disk, handles embedding generation, and exposes a collections API that abstracts the rest. It's the right first vector database for prototypes and small-to-medium production workloads before you need horizontal scale.
Install
pip install chromadb sentence-transformers
Create a persistent client and collection
import chromadb
from chromadb.utils import embedding_functions
# PersistentClient writes to disk; survives restarts
client = chromadb.PersistentClient(path="./my_vectorstore")
ef = embedding_functions.SentenceTransformerEmbeddingFunction(
model_name="all-MiniLM-L6-v2" # free, runs locally, 384-dim
)
collection = client.get_or_create_collection(
name="docs",
embedding_function=ef,
metadata={"hnsw:space": "cosine"} # cosine similarity
)
Switch to in-memory with chromadb.EphemeralClient() for tests; switch to chromadb.HttpClient(host=..., port=...) to point at a deployed server — no other code changes needed.
Add documents with metadata
collection.add(
ids=["doc1", "doc2", "doc3"],
documents=[
"LLMs can be fine-tuned on domain-specific datasets.",
"Prompt caching reduces API costs by 90% on repeated context.",
"pgvector adds vector search to any PostgreSQL database.",
],
metadatas=[
{"topic": "fine-tuning", "level": "intermediate"},
{"topic": "api-cost", "level": "beginner"},
{"topic": "database", "level": "intermediate"},
]
)
ChromaDB calls your embedding_function automatically — you pass raw text, not vectors.
Query by meaning and filter simultaneously
results = collection.query(
query_texts=["how do I reduce my model API costs"],
n_results=2,
where={"level": "beginner"}, # metadata filter applied before ranking
include=["documents", "distances", "metadatas"]
)
print(results["documents"])
# → [["Prompt caching reduces API costs by 90% on repeated context."]]
print(results["distances"])
# → [[0.12]] (lower = more similar under cosine)
The where clause narrows the ANN search to the matching metadata subset — you get semantic ranking within the filtered population, not a post-filter on top of all results.
Swap the embedding function
The embedding_function= argument accepts any callable. Built-in options include OpenAIEmbeddingFunction, CohereEmbeddingFunction, and HuggingFaceEmbeddingFunction. Replace the constructor argument and the rest of the code stays identical — the API is model-agnostic.
When to graduate from ChromaDB
ChromaDB handles millions of vectors comfortably on a single node. When you need horizontal sharding, multi-region replication, or tight PostgreSQL integration, move to Qdrant, Weaviate, or pgvector. But for most learning projects and production prototypes, ChromaDB gets you there with zero ops overhead.
Sources: Mastering ChromaDB: Step-by-Step Python Guide (YouTube, July 2026) · ChromaDB Docs — Getting Started · ChromaDB Tutorial: From pip install to RAG Pipeline — TopicTrick