This episode covers ChromaDB observability and operations: health checks, latency and throughput metrics, logging, OpenTelemetry instrumentation with traceAI-chromadb, routine backup and restore, capacity planning, and incident response.

All of ChromaDB's strengths mean nothing if you are blind to what is happening. Episode 20 covers observability and operations — the eyes and hands of a production system: health checks, metrics, logging, OpenTelemetry instrumentation, routine backups, capacity planning, and incident response.
The combination of observability and operations is what separates "an app that runs" from "a system that is managed". You will see how to monitor the server, measure performance, and prepare for failures.
ChromaDB provides a simple health endpoint. Periodic verification is the most basic observability gateway:
curl http://localhost:8000/api/v2/heartbeatcurl http://localhost:8000/api/v2/heartbeat returns a timestamp — a sign the server is alive. For automated monitoring, schedule this health check every few seconds:
while true; do
curl -fsS http://localhost:8000/api/v2/heartbeat && echo " OK $(date)"
sleep 10
doneThe loop above prints status every 10 seconds. In production, replace it with an orchestrator probe — Kubernetes livenessProbe and readinessProbe mirror exactly this pattern.
Metrics you must monitor for ChromaDB:
query takes.Measure latency from the application side:
import time
start = time.perf_counter()
hasil = collection.query(query_texts=["deploy"], n_results=5)
latensi_ms = (time.perf_counter() - start) * 1000
print(f"latensi query: {latensi_ms:.1f} ms")latensi_ms = (time.perf_counter() - start) * 1000 calculates the duration of a single query. Track p50 and p99 values over the long term — a p99 shift signals index degradation or shrinking RAM.
In production, metrics must flow to a backend such as Prometheus. Instrumentation happens at the application layer: measure each query, export it as a histogram, and let Prometheus scrape it. Implementation details depend on your stack — what matters is consistency between how you measure and how you store.
Info
Start simple: heartbeat for availability, latency and throughput for performance, and error rate for health. Add other metrics only when it is clear what decision you will make from those numbers.
Good logs have context: collection, query, and results. Example of structured logging from the client application:
import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("chroma-app")
log.info(
"query collection=%s n=%s latensi_ms=%.1f",
"dokumen", 5, latensi_ms,
)log.info("query collection=%s n=%s latensi_ms=%.1f", ...) writes logs with structured fields. Consistent logs make troubleshooting easier — for example, "all queries with latency above 1 second".
For end-to-end tracing of the RAG pipeline, use OpenTelemetry. The Chroma ecosystem provides traceAI-chromadb, an adapter that connects ChromaDB instrumentation to OpenTelemetry backends:
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(endpoint="http://collector:4318")))provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(endpoint="http://collector:4318"))) sends traces to an OpenTelemetry collector. With proper instrumentation, every RAG request can be traced: embed, query, filter, and the LLM answer — seeing where the most time is lost.
Episode 11 taught how to back up data; episode 20 makes backups routine. Schedule with cron:
0 2 * * * rsync -a --delete /data/chroma/ /backup/chroma-daily/The cron line above runs rsync -a --delete /data/chroma/ /backup/chroma-daily/ every day at 02:00. Also keep a snapshot off-machine — a backup that stays on the same server will not save you from disk failure.
A backup that has never been tested is not a backup. Schedule a restore test in a separate environment at least once a month: copy the backup, run the server from it, then verify collection counts and basic queries. This process finds broken backups before an emergency arrives.
Capacity planning answers "when do we need to add resources?". Monitor three signals:
A simple rule: when RAM usage reaches 70 percent of the allocation, start planning the upgrade. Do not wait for p99 to skyrocket.
Prepare a minimal runbook before an incident:
def cek_server(client):
try:
client.heartbeat()
print("server: sehat")
return True
except Exception as e:
print("server: bermasalah ->", e)
return False
if not cek_server(client):
print("jalankan: systemctl restart chroma")The cek_server(client) function automates initial detection. A documented runbook makes the first incident feel like a drill, not a disaster.
Episode 20 gave ChromaDB eyes and hands: heartbeat health checks, latency and throughput metrics, structured logging, OpenTelemetry tracing with traceAI-chromadb, tested routine backup and restore, capacity planning from RAM and growth signals, and a clear incident response runbook.
Key takeaways:
In the next episode, episode 21, we will discuss modern features and the roadmap — ChromaDB's 2026 capabilities: vector, full-text, regex, and metadata in one engine, weekly releases, the Rust server for production, Chroma Cloud, and the direction toward serverless and multi-node development. You will know where this technology is moving.