ChromaDB Vector Store Integration for AI in Mobile Applications
ChromaDB is a lightweight open-source vector database written primarily for the Python ecosystem. Runs in-memory, embedded, or as a server. Main advantage — minimal entry barrier: pip install chromadb and three lines of code until first search.
ChromaDB's Role in Mobile Context
Honest answer: ChromaDB is a backend solution, not for mobile. iOS and Android don't run ChromaDB natively. Integrating it into a mobile application means:
- ChromaDB server on your backend (Python/FastAPI) + REST API for mobile client
- Python scripts for offline document indexing + result export
This differentiates ChromaDB from Pinecone (managed cloud) and Weaviate (supports Java/TS clients). ChromaDB is the right choice for prototypes, small internal tools, and startups with Python backend wanting to quickly add RAG.
Basic Integration on Python Backend
import chromadb
from chromadb.config import Settings
# Persistent client (stores data on disk)
client = chromadb.PersistentClient(path="/data/chroma")
# Collection with cosine metric
collection = client.get_or_create_collection(
name="knowledge_base",
metadata={"hnsw:space": "cosine"}
)
# Adding documents
collection.add(
documents=["text chunk 1", "text chunk 2"],
embeddings=[[0.1, 0.2, ...], [0.3, 0.4, ...]], # your embeddings
metadatas=[
{"source": "manual.pdf", "user_id": "42", "lang": "ru"},
{"source": "faq.txt", "user_id": "42", "lang": "ru"}
],
ids=["doc1_chunk1", "doc1_chunk2"]
)
If you don't pass embeddings, ChromaDB creates them via built-in DefaultEmbeddingFunction (Sentence Transformers all-MiniLM-L6-v2). Convenient for prototyping, but slow for production — better to generate embeddings separately in batch.
FastAPI Wrapper for Mobile Client
from fastapi import FastAPI, Depends
from pydantic import BaseModel
app = FastAPI()
class SearchRequest(BaseModel):
query: str
user_id: str
limit: int = 5
@app.post("/api/search")
async def search(req: SearchRequest, user=Depends(get_current_user)):
# Verify user_id matches authenticated user
if req.user_id != user.id:
raise HTTPException(status_code=403)
query_embedding = embedder.embed(req.query)
results = collection.query(
query_embeddings=[query_embedding],
n_results=req.limit,
where={"user_id": req.user_id}, # user filter
include=["documents", "metadatas", "distances"]
)
return format_results(results)
Mobile client calls /api/search — no direct ChromaDB access.
Limitations You Should Know Before Integration
Multi-tenancy through metadata filter. ChromaDB lacks native user isolation like Weaviate tenants. Isolation only through where={"user_id": ...}. With many users or documents, this becomes slow — filter applies after ANN, not before.
No horizontal scaling. ChromaDB is not distributed. Single node. For large products (10M+ vectors, high RPS) this is limiting. For startups up to 500K documents — sufficient.
No built-in hybrid search. Vector search only. For quality RAG you'll add BM25 manually (e.g., via rank_bm25 Python library) and do RRF merging of results.
# RRF (Reciprocal Rank Fusion) for hybrid search
def rrf_merge(vector_results, bm25_results, k=60):
scores = {}
for rank, doc_id in enumerate(vector_results):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
for rank, doc_id in enumerate(bm25_results):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
return sorted(scores.keys(), key=lambda x: scores[x], reverse=True)
Migrating from ChromaDB to Production Systems
ChromaDB often serves as a starting point, then migrate to Weaviate or pgvector as load grows. This is normal. Make your search interface abstract from the start:
class VectorStore(ABC):
@abstractmethod
def search(self, embedding: List[float], user_id: str, limit: int) -> List[Document]:
pass
class ChromaVectorStore(VectorStore): ...
class WeaviateVectorStore(VectorStore): ...
Implementation swap won't affect mobile API.
Implementation Timeline
Deploy ChromaDB server → FastAPI wrapper with authentication → ingestion scripts → search endpoint for mobile client → test quality → monitoring.
MVP with ChromaDB and basic RAG — 1–2 weeks. Production variant with hybrid search and proper user isolation — 3–4 weeks.







