fix(server): compact superseded history and reclaim database space

Closed
JU
7d ago
+1687-15

Remove superseded events automatically. New databases shrink in background batches; existing databases can enable this with t3 doctor --fix. Reconnects fall back to snapshots after history cleanup.

CommandBehavior
t3 doctorChoose repairs; recommended set preselected
t3 doctor --dry-runPreview repairs; overrides --fix
t3 doctor --fixApply recommended repairs without prompting

Web/desktop Storage settings and mobile Maintenance show a dismissible notice when an older database has at least 1 GiB to reclaim. The copied command includes that environment's data directory. The CLI shows a stage bar and elapsed time during repairs. Doctor restores a service it paused even after repair failure/cancellation, leaves already-stopped and other environments' services alone, and documents the workflow in a dedicated user guide. Desktop/manual servers must be closed first.

Measured on a copy of the maintainer's database

MetricBeforeAfter compaction + VACUUMImprovement
Database file114.46 GB19.67 GB94.79 GB reclaimed
Stored events2,922,8072,023,88231% fewer
Event JSON98.72 GB7.13 GB93% less
Full-history replay-stat scan6.66 s1.01 s6.6× faster
Recent 1,000-sequence replay-stat scan0.393 ms0.048 ms8.1× faster
Event-count index scan10.89 ms3.55 ms3.1× faster
Event-index ANALYZE1.97 s0.95 s2.1× faster
One-time maintenanceDuration
Delete 898,925 obsolete events6 min 12 s
VACUUM + checkpoint4 min 6 s

Deletion alone reduced the full-history scan to 2.08 s; VACUUM reduced it further to 1.01 s. Automatic deletion starts after one minute and repeats every six hours, in 50-row batches. Full VACUUM is explicit and offline. Converted/new databases reclaim up to 1,024 pages per minute while running.

Method: Node 24.21.0 / SQLite 3.53.4, Apple M4 Max, 64 GB RAM. Medians of 3 scan/ANALYZE runs, 5 count runs, and 11 recent-range runs. Cache state was not controlled. Full-history scanning is a diagnostic upper bound; normal reconnects are capped. The same recent range returned 1,000 rows before and 331 after deletion. Startup optimize took 7.4 ms before and 1.2 ms after; the original 30-second delay was not reproduced.

Limitation: The guarded CLI refused one pre-existing unreadable thread projection. Benchmarks therefore invoked the underlying compactor and VACUUM directly on the disposable copy. The live database was untouched.

Validation: original 146 focused tests; 45 focused tests for doctor, database maintenance, storage status, scheduling, authorization and instrumentation. Server/web/mobile typechecks and targeted lint pass. 77 focused CLI/service/database tests cover selection, automatic service handling, dry-run isolation and progress. Isolated CLI dry run confirmed while the server was running.

UI verification is pending: the built-in browser timed out twice on snapshots. No screenshots are claimed.

Implemented with GPT-6.1 Sol via Codex.

Doctor recording

Throwaway database: 769.59 → 257.40 MiB, reclaiming 512.19 MiB. Recommended repair selected by default; colors, headings and stage progress shown below. Retained data verified. No installed service in this fixture; the recording harness stops the CLI after the completion summary.

Doctor repair selection and completion

· Terminal recording

CLI styling: 9 focused tests, server typecheck and targeted lint pass.