Skip to main content

Overview

Loom uses SQLite with Write-Ahead Logging (WAL) for thread persistence, authentication, analytics, and feature flags. The database is designed for multi-reader, single-writer workloads.
Database migrations run automatically on server startup. You do not need to run migrations manually.

Database Location

The database path is configured via:
Or in NixOS:

SQLite Configuration

Loom uses these SQLite settings:
  • Journal mode: WAL (Write-Ahead Logging) for better concurrency
  • Synchronous: NORMAL (balance between safety and performance)
  • Foreign keys: Enabled
  • Auto vacuum: Incremental

Schema Organization

The database schema is organized into these domains:

Threads

Conversation persistence and FTS search

Authentication

Users, organizations, teams, sessions, API keys

SCM

Git repositories, commits, webhooks, mirrors

Analytics

Events, sessions, crash reports, cron monitoring

Feature Flags

Flags, experiments, exposures

Secrets

Weaver secrets with encryption-at-rest

Migration System

Migrations are numbered SQL files in crates/loom-server/migrations/:

Migration Naming Convention

  • NNN: Three-digit sequence number (001, 002, …)
  • description: Short snake_case description
Examples:
  • 020_scm_repos.sql
  • 030_feature_flags.sql
  • 032_analytics.sql

How Migrations Run

Migrations are embedded in the binary via include_str!() and executed sequentially on startup:
crates/loom-server/src/db/mod.rs
cargo2nix doesn’t track include_str!() file changes. After adding migrations:
  1. Run cargo2nix-update to regenerate Cargo.nix
  2. Commit Cargo.nix along with your migration files
  3. Without this step, the deployed binary will NOT include the new migration!

Adding a Migration

1

Find the next migration number

2

Create the migration file

3

Write the migration SQL

041_my_feature.sql
Always use IF NOT EXISTS and IF NOT EXISTS for idempotency. Migrations may be run multiple times.
4

Add the migration to db/mod.rs

crates/loom-server/src/db/mod.rs
5

Test the migration

6

Force rebuild for cargo2nix

Migration Examples

Simple Table Creation

020_scm_repos.sql

Full-Text Search (FTS5)

005_thread_fts.sql

JSON Columns

030_feature_flags.sql

Adding Columns to Existing Tables

023_add_username.sql

Schema Inspection

List All Tables

Show Table Schema

Show Indexes

Query Metadata

Database Backup

Manual Backup

Online Backup

Automated Backups

backup-service.nix

Database Maintenance

Vacuum

Reclaim space and defragment:

Analyze

Update query optimizer statistics:

Check Integrity

Optimize

Monitoring

Database Size

Table Sizes

WAL Status

Troubleshooting

This is expected behavior for idempotent migrations. The error is caught and ignored:
If a different error occurs, check the migration SQL syntax.
SQLite uses WAL mode for better concurrency, but you may still see lock errors with many concurrent writes.Fix:
  1. Ensure only one writer process (loom-server)
  2. Close SQLite CLI sessions before starting the server
  3. Check for stale lock files: rm -f /var/lib/loom-server/*.db-shm
cargo2nix doesn’t track include_str!() file changes.Fix:
Check that FTS triggers are installed:
Rebuild FTS index:

Current Schema (as of migration 040)

The database includes 40+ tables:
  • Threads: threads, thread_fts, thread_repos, thread_commits
  • Auth: users, orgs, teams, sessions, api_keys, impersonation_sessions
  • SCM: scm_repos, scm_webhooks, scm_mirrors, scm_maintenance_log
  • GitHub: github_installations, github_installation_repos
  • Analytics: analytics_events, analytics_user_aliases, sessions, session_aggregates
  • Crashes: crash_events, crash_api_keys, crash_symbol_artifacts
  • Feature Flags: flags, flag_exposures
  • Crons: cron_monitors, cron_checkins
  • Jobs: job_runs
  • Secrets: weaver_secrets
  • WhatsApp: whatsapp_orgs, whatsapp_inbound_messages
  • Misc: cse_cache, ws_tokens, docs_fts, wgtunnel_tunnels, clips, clip_stars

Next Steps

Server Setup

Deploy loom-server

Configuration

Environment variables reference