Module 4: ChromaDB Setup and Configuration

Capsule 02: ChromaDB Installation and Setup

🎯 Capsule objective

Install ChromaDB correctly, understand client modes (ephemeral, persistent, client-server), and create your first working collection.

By the end of this capsule:

  • ✅ ChromaDB installed and working
  • ✅ You'll understand client modes and when to use each one
  • ✅ First collection created (hello world)
  • ✅ Successful installation verification

Estimated time: 12-15 minutes


📦 Installation

Step 1: Install ChromaDB

# Option A: In a virtual environment (recommended)
python -m venv venv
source venv/bin/activate  # Mac/Linux
# venv\Scripts\activate   # Windows

pip install chromadb

# Option B: Global (not recommended)
pip install chromadb

Recommended version: 0.4.22+ (latest stable)

Step 2: Verify the installation

import chromadb

print(f"ChromaDB version: {chromadb.__version__}")
# Expected output: ChromaDB version: 0.4.22 (or higher)

If it works → ✅ Successful installation

Common troubleshooting

Error 1: "No module named 'chromadb'"

# Fix: Make sure the virtual env is activated
which python  # Should point to venv/bin/python
pip install chromadb

Error 2: "ImportError: DLL load failed" (Windows)

# Fix: Install the Microsoft Visual C++ Redistributable
# https://aka.ms/vs/17/release/vc_redist.x64.exe

Error 3: Dependency conflicts

# Fix: Create a clean virtual environment
rm -rf venv
python -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install chromadb

🔧 Client Modes

Mode 1: Ephemeral Client (In-Memory)

Use: Testing, quick prototyping

import chromadb

# Create an in-memory client
client = chromadb.Client()

# Data is lost when the process ends
collection = client.create_collection("test")
collection.add(documents=["hello"], ids=["1"])

print(collection.count())  # Output: 1

# When you close Python → Data disappears

Advantages:

  • ✅ Instant setup (no config)
  • ✅ Fast (everything in RAM)
  • ✅ Perfect for unit tests

Disadvantages:

  • ❌ Data does not persist
  • ❌ Not shareable across processes

When to use: Unit tests, quick experimentation.

Mode 2: Persistent Client (Disk Storage)

Use: Development, local production

import chromadb

# Create a client with persistence
client = chromadb.PersistentClient(path="./chroma_db")

# Data persists on disk
collection = client.create_collection("docs")
collection.add(documents=["hello"], ids=["1"])

# Close and reopen Python
# Data is still available
client2 = chromadb.PersistentClient(path="./chroma_db")
collection2 = client2.get_collection("docs")
print(collection2.count())  # Output: 1 (it persisted!)

Advantages:

  • ✅ Data persists
  • ✅ Simple backups (copy the folder)
  • ✅ Production-ready (single machine)

Disadvantages:

  • ❌ Single process (concurrent writes not safe)
  • ❌ Not distributed

When to use: Development, MVP, single-node production.

Mode 3: Client-Server (HTTP)

Use: Multi-process production, remote access

# Terminal 1: Start the server
# chroma run --path ./chroma_db

# Terminal 2: Connect as a client
import chromadb

client = chromadb.HttpClient(host="localhost", port=8000)
collection = client.create_collection("docs")
collection.add(documents=["hello"], ids=["1"])

Advantages:

  • ✅ Multi-process (concurrent queries safe)
  • ✅ Remote access (network)
  • ✅ Production-ready

Disadvantages:

  • ❌ Requires a running server
  • ❌ More complex setup

When to use: Multi-process production, microservices.

Comparison

FeatureEphemeralPersistentClient-Server
Persistence❌ No✅ Yes✅ Yes
Setup✅ Instant✅ Simple⚠️ Medium
Multi-process❌ No❌ No✅ Yes
Production❌ No⚠️ Single-node✅ Yes
Typical useTestingMVP/DevProduction

Recommendation for this module: Use the Persistent Client (a balance between simplicity and persistence).


🎯 First Collection - Hello World

Complete code

import chromadb

# 1. Create a persistent client
client = chromadb.PersistentClient(path="./chroma_db")

# 2. Create a collection
collection = client.create_collection(name="hello_world")

# 3. Add documents
collection.add(
    documents=["Hello World", "Goodbye World"],
    metadatas=[{"type": "greeting"}, {"type": "farewell"}],
    ids=["1", "2"]
)

# 4. Query
results = collection.query(
    query_texts=["Hello"],
    n_results=2
)

# 5. Output
print(f"Documents: {results['documents']}")
print(f"Distances: {results['distances']}")
print(f"Metadatas: {results['metadatas']}")

Expected output:

Documents: [['Hello World', 'Goodbye World']]
Distances: [[0.4977, 1.3587]]
Metadatas: [[{'type': 'greeting'}, {'type': 'farewell'}]]

Line-by-line explanation

# 1. Client setup
client = chromadb.PersistentClient(path="./chroma_db")
# Creates the ./chroma_db folder if it doesn't exist
# Uses SQLite as the storage backend (chroma.sqlite3 file)

# 2. Collection
collection = client.create_collection(name="hello_world")
# Default HNSW index (M=16, space=cosine)
# If the collection exists → error (use get_or_create_collection)

# 3. Add documents
collection.add(
    documents=["Hello World", "Goodbye World"],
    # ChromaDB generates embeddings automatically (default model)
    
    metadatas=[{"type": "greeting"}, {"type": "farewell"}],
    # Metadata for filtering (optional)
    
    ids=["1", "2"]
    # Unique IDs required
)

# 4. Query
results = collection.query(
    query_texts=["Hello"],
    # ChromaDB embeddings automatically
    
    n_results=2
    # Top-2 most similar documents
)

# 5. Results structure
# {
#   'documents': [[...]], 
#   'distances': [[...]],  # Cosine distance (0=identical)
#   'metadatas': [[...]],
#   'ids': [[...]]
# }

✅ Setup Verification

Test 1: Basic functionality

import chromadb

def test_basic():
    client = chromadb.Client()  # Ephemeral for the test
    collection = client.create_collection("test")
    
    # Add
    collection.add(documents=["doc1"], ids=["1"])
    
    # Query
    results = collection.query(query_texts=["doc1"], n_results=1)
    
    # Assert
    assert results['ids'][0][0] == "1", "Query failed"
    assert len(results['documents'][0]) == 1, "Wrong count"
    
    print("✅ Basic functionality: PASS")

test_basic()

Test 2: Persistence

import chromadb
import os

def test_persistence():
    path = "./test_chroma_db"
    
    # Session 1: Create and add
    client1 = chromadb.PersistentClient(path=path)
    collection1 = client1.get_or_create_collection("persist_test")
    collection1.add(documents=["persist"], ids=["1"])
    
    # Simulate restart
    del client1
    
    # Session 2: Retrieve
    client2 = chromadb.PersistentClient(path=path)
    collection2 = client2.get_collection("persist_test")
    count = collection2.count()
    
    # Cleanup
    import shutil
    shutil.rmtree(path)
    
    # Assert
    assert count == 1, "Persistence failed"
    print("✅ Persistence: PASS")

test_persistence()

Test 3: HNSW configuration

import chromadb

def test_hnsw_config():
    client = chromadb.Client()
    
    # Collection with custom HNSW
    collection = client.create_collection(
        name="hnsw_test",
        metadata={
            "hnsw:space": "cosine",
            "hnsw:M": 32
        }
    )
    
    # Verify metadata
    metadata = collection.metadata
    assert metadata["hnsw:space"] == "cosine", "Config failed"
    
    print("✅ HNSW configuration: PASS")

test_hnsw_config()

If the 3 tests pass → ✅ Complete and working setup


🐛 Debugging Tips

Problem 1: "Collection already exists"

# ❌ Error
collection = client.create_collection("docs")
collection = client.create_collection("docs")  # Error!

# ✅ Fix: Use get_or_create_collection
collection = client.get_or_create_collection("docs")

# Or delete first
client.delete_collection("docs")
collection = client.create_collection("docs")

Problem 2: "IDs must be unique"

# ❌ Error
collection.add(documents=["a", "b"], ids=["1", "1"])  # Duplicate ID

# ✅ Fix: Unique IDs
collection.add(documents=["a", "b"], ids=["1", "2"])

Problem 3: The persistence folder grows a lot

# Cause: Not cleaning up old collections

# ✅ Fix: Delete unused collections
client.delete_collection("old_collection")

# Or reset completely
client.reset()  # ⚠️ Deletes ALL collections

✅ Comprehension checklist

  • What's the difference between an Ephemeral and a Persistent client?

    • Ephemeral: In-memory, doesn't persist. Persistent: Disk, persists.
  • When to use Client-Server mode?

    • Multi-process, remote access, distributed production.
  • How to verify that ChromaDB is working?

    • Create a collection, add a doc, query, verify results.
  • What to do if "Collection already exists"?

    • Use get_or_create_collection() or delete_collection() first.

If you answered 4/4 → ✅ Ready for Capsule 03 (HNSW Configuration)


🚀 Next step

You now have ChromaDB working! Now you'll learn to configure HNSW to optimize accuracy and latency.

Next capsule: 03 - Collection Configuration (HNSW Parameters)

You'll learn:

  • Configure M, efConstruction, efSearch
  • Choose a distance metric (cosine vs L2)
  • Benchmark configurations (A/B testing)
  • Validate the accuracy vs latency trade-off

Time: 12-15 minutes
Next: 03-collection-configuration.md