Two ways to deploy Chroma as a lightweight vector DB: pip-install it as an embedded library, or run the official Docker image as a server. Both work. Only one is the right choice for production.
The pip route (pip install chromadb) is faster to set up and great for notebooks, but it pins your DB lifecycle to a single Python process – kill the process, lose the connection pool. The Docker route gives you a real HTTP server on port 8000, multiple clients, and a clean upgrade path. For anything beyond a prototype, run the container. That’s the path we’ll cover in depth, with the pip option as a fallback.
The current release is Chroma 1.5.9, tagged on 2026-05-05. New tagged versions ship on Mondays, hotfixes any time (as of May 2026) – so if you’re reading this a few weeks later, bump the tag and the pip pin to match.
System requirements for a lightweight vector DB
Chroma is lightweight in CPU terms – it’ll happily run on a laptop. The numbers that bite you are disk and RAM, because vectors aren’t text.
| Resource | Minimum | Recommended |
|---|---|---|
| OS | Linux, macOS, Windows (WSL2) | Linux for prod |
| Python (pip install) | 3.8 | 3.11+ |
| SQLite | 3.35.0 | 3.40+ |
| RAM | 2 GB | 8+ GB |
| Disk | 10 GB | 2-4× your RAM |
Here’s a mental model worth keeping: most people think “I have 100MB of documents, so I need 100MB of storage.” That’s off by roughly two orders of magnitude. 1 GB of source text balloons to roughly 15 GB of vectors, and Chroma also persists the HNSW vector index, a metadata index, and a write-ahead log on top of that – so plan for 2-4× your RAM in disk space. The WAL alone can spike during heavy ingest. Get this wrong in development and you’ll be debugging mysteriously frozen containers in prod.
Install Chroma 1.5.9 with Docker (recommended)
One command, real server, persistent volume:
docker run -d
--name chroma
-p 8000:8000
-v $(pwd)/chroma-data:/data
-e ALLOW_RESET=TRUE
chromadb/chroma:1.5.9
A few notes on what each flag does and why it matters:
-v $(pwd)/chroma-data:/data– without this, your collections vanish when the container restarts. Most quickstarts omit it. Don’t.ALLOW_RESET=TRUE– lets the client wipe the DB programmatically. Turn this OFF for production.- The image tag is pinned.
:latestworks but you’ll regret it on a Monday morning when the weekly release breaks your client.
The Spring AI reference docs use the GHCR image (ghcr.io/chroma-core/chroma) instead of Docker Hub – same binary, different registry. Pick whichever your CI already authenticates against.
Alternative: pip install (embedded mode)
pip install chromadb==1.5.9
chroma run --path ./chroma_db_path --host localhost --port 8000
This gives you the same HTTP server without Docker. Good for laptops, bad for anything you need to monitor.
First-time configuration and a sanity check
Minimum viable config: nothing. Out of the box, Chroma uses an in-process default embedding model (all-MiniLM-L6-v2 via Sentence Transformers, as of May 2026), no API key needed. Confirm the server is alive:
curl http://localhost:8000/api/v2/heartbeat
# expected: {"nanosecond heartbeat": 1736...}
Then a 30-second Python verification – this proves your client can talk to the container, not just that the port is open:
import chromadb
client = chromadb.HttpClient(host="localhost", port=8000)
col = client.get_or_create_collection("smoke_test")
col.add(
documents=["chroma 1.5.9 deployed", "vector db running"],
ids=["a", "b"]
)
print(col.query(query_texts=["is it working"], n_results=1))
If you see a result with one of those two IDs, you’re done.
Pro tip: Pin the chromadb client version to match the server EXACTLY. A 1.5.9 server talking to a 1.4.x client will throw cryptic schema errors that look like data corruption but aren’t.
The SQLite 3.35 trap (the one that wastes hours)
This is the error you’ll hit on Debian slim images, PythonAnywhere, GitHub Codespaces, and any Ubuntu 20.04-based base:
RuntimeError: Your system has an unsupported version of sqlite3.
Chroma requires sqlite3 >= 3.35.0.
The trap: sqlite3 isn’t a pip package. It ships with Python, bound to whatever your OS provides. You can’t pip install sqlite3 – it doesn’t exist. The community-discovered fix (now in the official troubleshooting docs) is to install a userspace SQLite and swap it into sys.modules before anything imports the stdlib version:
pip install pysqlite3-binary
# Add to the TOP of your entrypoint, before any chromadb import:
__import__('pysqlite3')
import sys
sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
import chromadb # now safe
Why does this happen with Docker too? Because Python’s official slim images inherit Debian’s older SQLite. The Chroma Docker image itself is fine – but if you’re building a custom image with FROM python:3.10-slim and pip-installing chromadb, you’ll hit it. Use python:3.11 (not slim) or apply the monkey-patch above.
Other install errors worth knowing
- macOS clang error:
clang: error: the clang compiler does not support '-march=native'– setexport HNSWLIB_NO_NATIVE=1before pip install, then runxcode-select --installif it persists. - Container restarts wipe data: you forgot the
-vvolume mount. Add it and re-create. - Connection refused from another container:
localhostinside a container means the container itself. Use the Chroma container’s name on a shared Docker network.
Upgrades, migration gotchas, and clean removal
At v1.0.0, Chroma quietly added embedding function persistence to collections. Before that – versions 0.6.3 and earlier – no persistence. What that means in practice: upgrade to 1.5.9 and reconnect to an old collection, and you must specify the embedding function on every get_collection() call, or queries silently return garbage. New collections created on any 1.x version remember. Old ones don’t, and nothing warns you.
Standard upgrade flow:
# 1. Stop the old container, keep the volume
docker stop chroma && docker rm chroma
# 2. Pull the new tag
docker pull chromadb/chroma:1.5.9
# 3. Restart with same volume
docker run -d --name chroma -p 8000:8000
-v $(pwd)/chroma-data:/data
chromadb/chroma:1.5.9
For complete removal:
docker stop chroma && docker rm chroma
docker rmi chromadb/chroma:1.5.9
rm -rf ./chroma-data # ← this deletes your vectors. final.
# pip install variant:
pip uninstall chromadb
rm -rf ./chroma_db_path
The rm -rf on your data directory is final. No soft-delete, no recycle bin. If you want it back, you wanted a backup.
When Chroma is the wrong choice
Honest take: Chroma is Apache-2.0, used in 90k+ open-source codebases with 11M+ monthly downloads (as of May 2026 per trychroma.com). Hard to argue with that for prototypes and small-to-medium RAG apps.
But “lightweight” has limits. If your collection grows past a few million vectors on a single node, the HNSW index will demand more RAM than you want to pay for, and you’ll start looking at sharded options or Chroma Cloud. If you need an embedded DB (no separate process at all), look at chromem-go for Go, or sqlite-vss for a pure SQLite play. Both trade features for a smaller footprint.
FAQ
Does Chroma need a GPU?
No. The DB itself is CPU-only. A GPU only helps if you’re generating embeddings locally with a model like Sentence Transformers – and even then, only at ingest time, not at query time.
Can I run Chroma serverlessly on something like AWS Lambda?
Not in the way most people mean. Chroma writes to disk (HNSW + WAL + SQLite), and Lambda’s ephemeral filesystem nukes that between cold starts. You’d lose collections on every cold boot. A workable pattern is mounting EFS or running Chroma on a small Fargate task that Lambda calls over HTTP – but at that point you’ve reinvented a server. If you want true serverless, that’s what Chroma Cloud exists for.
Is the default embedding model good enough for production?
For English semantic search on short text, all-MiniLM-L6-v2 is genuinely decent and free. For multilingual, code search, or long-context retrieval, swap to OpenAI text-embedding-3-small or a Voyage/Cohere model. The catch is consistency: queries must use the same model as ingest, or distances are meaningless.
Next step: spin up the Docker command at the top of this guide, run the curl heartbeat check, then point one real document set at it – your own notes, a folder of PDFs, anything. Five minutes of real data tells you more than an hour of toy examples.