Skip to content

title: ChromaDB description: Developer-friendly vector database — ChromaDB for RAG: embeddings, metadata filtering, persistence, and integration with LangChain and LlamaIndex. category: 09-RAG tags: [chroma, chromadb, vector-store, rag, developer] status: ready last_updated: 2026-09-06


ChromaDB

Chroma is the developer-friendly vector database. It runs in-process (no server needed), persists to disk, and integrates seamlessly with LangChain and LlamaIndex. Use Chroma when you want a simple, local vector DB without the overhead of FAISS setup or a managed service.

Table of Contents

Installation / Setup

pip install chromadb                    # or: uv add chromadb

Core Syntax

Basic usage

import chromadb

# create a client (in-memory by default)
client = chromadb.Client()

# or persistent client (saves to disk)
client = chromadb.PersistentClient(path="./chroma_db")

# create a collection
collection = client.get_or_create_collection(
    name="documents",
    metadata={"hnsw:space": "cosine"},   # or "l2", "ip"
)

# add documents
collection.add(
    documents=["Python is great for ML", "JavaScript runs in browsers"],
    ids=["doc1", "doc2"],
    metadatas=[{"source": "tutorial"}, {"source": "web"}],
)

# query
results = collection.query(query_texts=["data analysis"], n_results=3)
print(results["documents"])     # [['Python is great for ML']]
print(results["distances"])     # [[0.35]] (lower = more similar for cosine)

Collection settings

collection = client.get_or_create_collection(
    name="my_docs",
    metadata={
        "hnsw:space": "cosine",     # "cosine", "l2", or "ip"
        "hnsw:M": 16,               # connections per node (default 16)
        "hnsw:ef_construction": 200, # build quality (default 200)
    },
)

LangChain + Chroma

from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings

# create from documents
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=OpenAIEmbeddings(),
    collection_name="my_docs",
    persist_directory="./chroma_db",    # optional: persist to disk
)

# search
docs = vectorstore.similarity_search("query", k=5)

# with metadata filter
docs = vectorstore.similarity_search(
    "query", k=5, filter={"source": "report.pdf"}
)

LlamaIndex + Chroma

import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import VectorStoreIndex, StorageContext

chroma_client = chromadb.PersistentClient(path="./chroma_db")
chroma_collection = chroma_client.get_or_create_collection("my_docs")

vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)

index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)

Common Operations

Metadata filtering

# exact match
results = collection.query(
    query_texts=["query"],
    where={"source": "report.pdf"},
)

# comparison operators
results = collection.query(
    query_texts=["query"],
    where={"year": {"$gte": 2024}},
)

# logical operators
results = collection.query(
    query_texts=["query"],
    where={"$and": [{"source": "report"}, {"year": {"$gte": 2024}}]},
)

Update and delete

# update
collection.update(
    ids=["doc1"],
    metadatas=[{"source": "updated_source"}],
)

# delete
collection.delete(ids=["doc1"])
collection.delete(where={"source": "old_source"})

Collection management

# list collections
collections = client.list_collections()

# get collection
collection = client.get_collection("my_docs")

# count documents
print(collection.count())

# delete collection
client.delete_collection("my_docs")

Practical Examples

Example 1 — Full RAG with Chroma

import chromadb
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# build Chroma store
vectorstore = Chroma.from_documents(
    chunks, OpenAIEmbeddings(), persist_directory="./chroma_db")
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

# RAG chain
rag = (
    {"context": retriever | (lambda d: "\n\n".join(x.page_content for x in d)),
     "question": RunnablePassthrough()}
    | ChatPromptTemplate.from_template("Answer:\n{context}\n\nQ: {question}")
    | ChatOpenAI(model="gpt-4o")
    | StrOutputParser()
)

Example 2 — ChromaDB standalone (no LangChain)

import chromadb
from openai import OpenAI

client_oa = OpenAI(api_key="YOUR_API_KEY")
client = chromadb.PersistentClient(path="./my_db")
collection = client.get_or_create_collection("docs")

def embed(texts):
    return client_oa.embeddings.create(model="text-embedding-3-small", input=texts)

# add with embeddings
response = embed(["doc1 text", "doc2 text"])
collection.add(
    documents=["doc1 text", "doc2 text"],
    embeddings=[e.embedding for e in response.data],
    ids=["1", "2"],
)

# query with embedding
query_emb = embed(["search query"])
results = collection.query(query_embeddings=query_emb.data[0].embedding, n_results=3)

Common Patterns

Pattern: persistent Chroma for RAG app

from langchain_community.vectorstores import Chroma

# first run: create and persist
vectorstore = Chroma.from_documents(chunks, embeddings, persist_directory="./db")

# subsequent runs: load from disk
vectorstore = Chroma(persist_directory="./db", embedding_function=embeddings)

Pattern: multi-tenant Chroma

# separate collections per tenant
for tenant_id in tenant_ids:
    collection = client.get_or_create_collection(
        name=f"docs_{tenant_id}",
        metadata={"hnsw:space": "cosine"},
    )

Best Practices

  • Use Chroma for local development and small-to-medium datasets.
  • Use PersistentClient for persistence — Client() is in-memory only.
  • Chroma uses its own embedding function by default — pass your own for custom models.
  • Metadata filtering is a key advantage over FAISS.
  • Chroma is not for production scale (>1M vectors) — use Qdrant, Pinecone, or Weaviate.

Common Mistakes

Mistake Fix
Using Client() in production Use PersistentClient(path="./db")
Not persisting Chroma in-memory loses data on restart
Expecting production scale Chroma is for dev/small; use managed DB for production
Wrong distance metric Check hnsw:space: cosine for normalized, l2 for raw

Troubleshooting

Symptom Cause / Fix
Data lost after restart Not using PersistentClient
Dimension mismatch Embedding model changed — re-embed
Slow queries on large data Chroma is not optimized for >1M vectors
Collection not found Check collection name; use get_or_create_collection

Official Documentation

Last Updated

2026-09-06 — Initial version.