2 min read · 390 words
Database Overview
Two stores, one principle: SQLite is the source of truth for everything; Chroma holds only derived, searchable embeddings.
The two stores
SQLite (agentops.db) | Chroma (chroma_db/) | |
|---|---|---|
| Holds | 9 relational tables — agents, messages, runs, tasks, tool calls, documents, chunks, workflow runs/steps | one collection (agent_documents) of chunk embeddings + metadata |
| Written by | routers via SQLAlchemy | document_service only |
| Location | backend/app/agentops.db (CWD-relative) | backend/app/chroma_db/ (CWD-relative) |
| Created | at boot (create_all) | on first upload |
| Committed to git | ❌ runtime artifact | ❌ runtime artifact |
| Rebuildable from the other? | no — authoritative | yes — from document_chunks.chunk_text |
The link between them is document_chunks.vector_id = the Chroma record ID (agent_{a}_document_{d}_chunk_{i}) — every vector is traceable to a row and vice versa (Ingestion).
Section pages
[Schema](schema.md)Full ERD, every table with every column, relationship and cascade rules.Schema
[Migrations](migrations.md)The `create_all` + startup-migration strategy, its guarantees, and its limits.Migrations
Working with the database in development
bash
# Inspect with the sqlite3 CLI (from backend/app/)
sqlite3 agentops.db ".tables"
sqlite3 agentops.db "SELECT id, name, enabled_tools FROM agents;"
sqlite3 agentops.db "SELECT tool_name, success, latency_ms, estimated_cost FROM tool_calls ORDER BY id DESC LIMIT 10;"
# Nuke and start fresh (dev only!)
rm agentops.db && rm -rf chroma_db/ # tables recreate on next boot; re-upload documentsDeleting agentops.db erases all agents, history, and telemetry; deleting chroma_db/ erases all embeddings (recoverable only by re-uploading). There are no backups unless you make them — cp agentops.db agentops.backup.db before risky experiments.
Operational characteristics
- Concurrency: SQLite is single-writer;
check_same_thread=Falseallows FastAPI's threadpool access, and request-scoped sessions keep write windows short (Database Layer). - Integrity: FK relationships with
cascade="all, delete"fromAgent— but note Chroma vectors do not cascade (Known Issues). - Portability: everything is files — copy the two paths and you've cloned the environment.
- Scaling path: SQLAlchemy keeps a Postgres migration close to a URL change + Alembic adoption + pgvector (or hosted Chroma) for vectors (Design Decisions).
Related pages
- ORM Models — the code defining the schema
- RAG Ingestion — the dual-write path