Releasing soon Vigo is in alpha and closing in on its first stable release. Expect breaking changes between releases until then — we're looking for testing partners with meaningful fleets across diverse architectures. Learn more →

vigocli db

Inspect and maintain the server's SQLite database.

Subcommands

stats

Show database file size, WAL size, page count, free-page count, and per-table row counts.

vigocli db stats

The free-page count is the freelist — space freed by deletes that SQLite reuses in place for new rows. A non-zero freelist is normal and healthy, not a leak; see Disk space and the freelist.

integrity

Run SQLite integrity checks (PRAGMA integrity_check and PRAGMA foreign_key_check).

vigocli db integrity

vacuum

Rewrite the database file to reclaim unused space freed by db prune or normal deletes. Streams progress every 5 seconds (elapsed time | bytes written / estimated total | pct estimate); the percentage is approximated from the process's write counter against an expected ~2× DB-size budget. On a multi-GB DB this can take many minutes — the streaming heartbeat lets you see it isn't stuck. Prompts for confirmation (use --yes to skip; required for non-interactive use).

vigocli db vacuum
vigocli db vacuum --yes

prune

Delete history rows older than a chosen age — runs (cascades run_results), task_runs, workflow_runs, file_snapshots, convergence_history, compliance_history. Same query path as the daily background pruner. Use this when you want to reclaim space immediately — typically after lowering database.retention from a higher value, or on a DB whose accumulated history predates the current window. Pair with vigocli db vacuum to return reclaimed pages to the OS.

vigocli db prune --older-than 30d
vigocli db prune --older-than 720h --yes

analyze

Refresh the query planner's table statistics. Runs ANALYZE, which updates sqlite_stat1 so SQLite's planner picks the best query plan. Worth running once after adding or dropping an index, after a large db prune, or whenever EXPLAIN QUERY PLAN seems to ignore an index that should be used. Typically seconds even on multi-GB databases.

vigocli db analyze

checkpoint

Force a WAL checkpoint to flush pending writes to the main database file.

vigocli db checkpoint

query

Execute a read-only SQL query against the database. Write operations (INSERT, UPDATE, DELETE, DROP) are blocked server-side.

vigocli db query "SELECT hostname, compliance_status FROM envoys"
vigocli db query "SELECT COUNT(*) FROM runs WHERE status = 'failure'"

reset

Permanently delete ALL data and recreate the schema. Requires typing "yes" to confirm (use --force to skip).

vigocli db reset
vigocli db reset --force

Disk space and the freelist

The database file grows to its working-set high-water mark and then plateaus: deleted rows go to a freelist of unused pages, and SQLite reuses those pages in place for new inserts rather than shrinking the file. A steady non-zero Free pages in db stats is healthy reuse slack — the file stops growing once retention pruning balances new data against expired data.

The file only shrinks on disk when you run db vacuum (a full rewrite — exclusive lock, ~2× disk, many minutes on a multi-GB DB). That's an occasional operator action, not routine maintenance: run it once after a large one-time db prune (e.g. right after enabling or lowering database.retention on a DB that accumulated more history than the new window allows), not on a schedule. The server has no automatic online shrink — under WAL, auto_vacuum/incremental_vacuum can't reclaim effectively, so the freelist-reuse plateau is the intended steady state. The daily retention pruner logs a one-line recommendation if the freelist ever grows large enough that a vacuum would meaningfully shrink the file.

If db backup (Litestream) is enabled, schedule any db vacuum deliberately: a full vacuum rewrites the entire file and triggers a complete re-replication to remote storage.