Repository navigation
Description
Note
Claude Opus 5.5 in Claude Code, writing on behalf of @tsmith165. Measured on his Mac on 2026-10-22.
Before submitting
-
I searched existing issues and did not find a duplicate. Related but different:
- orchestration_events grows without bound: streaming updates are stored as permanent events and never compacted #21154 (closed): compaction not running.
- [Bug]: History compaction reads every event's payload on each pass (1.1 GB scanned to delete 60 events) #21290 (closed): each pass reads every payload.
- [Bug]: Intermediate turn-item snapshots remain outside event compaction (78.5 MB on one install) #19780: turn items are not compacted.
This issue is about compaction not finishing on a large store, because progress is lost on each restart.
-
I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Use a database that was migrated from v1. It should hold a few million imported v1 thread events plus a few million v2 events.
- Start the server with no
userdata/compacted-atfile. Compaction starts 1 minute after startup. - Restart the server before the pass finishes, for example through a nightly update, a quit or a crash.
Expected behavior
Compaction eventually finishes. It deletes the v1 events of imported threads, which compactEventStore treats as obsolete.
Actual behavior
On this database userdata/compacted-at has never been written, and no "Compacted orchestration history" line appears in the logs we have. 3,210,165 v1 thread events remain (about 7 GiB). Every one of them belongs to a thread whose orchestration_v2_legacy_imports.transcript_imported_at is set, which is the exact rule compactEventStore uses to mark them obsolete.
Database: 44.2 GiB, with 6,618,661 events, 3,479,494 command receipts and auto_vacuum = 0.
From the 0.1.2-nightly.20261022.3526 bundle:
compactEventStorepages 50 events at a time, downward fromMAX(sequence). The v1 events have the lowest sequences (1 to 3,188,552), so a pass reaches them only after reading all 3.4M v2 events above them.- Progress is not saved.
throughSequencestarts again atMAX(sequence)on every start, and the marker is written only after a complete pass. A restart before then throws the work away. This machine restarts at least daily for nightly updates. - Each page also reads payloads ([Bug]: History compaction reads every event's payload on each pass (1.1 GB scanned to delete 60 events) #21290), which makes a full pass slower on a store this size.
Possible fixes:
- Delete imported v1 events with an indexed statement before the paged scan, in sequence batches:
DELETE FROM orchestration_events WHERE sequence BETWEEN ? AND ? AND application_event_version = 1 AND aggregate_kind = 'thread' AND stream_id IN (SELECT thread_id FROM orchestration_v2_legacy_imports WHERE transcript_imported_at IS NOT NULL). Its query plan usesidx_orchestration_events_application_sequence. Receipts work the same way withcommand_type = 'legacy'. - Persist the cursor, so a restart resumes where the last pass stopped.
Impact
Major degradation or frequent failure
Version or commit
0.1.2-nightly.20261022.3526
Environment
macOS (Darwin 25.5.0), T3 Code (Nightly) desktop app
Workaround
Quit the app, take a backup, run the batched DELETE above for events and legacy receipts, then run t3 doctor --fix. We are doing this today and can add the before and after numbers here.
Activity
tsmith165 commentedon Oct 22, 2026
Note
Claude Opus 5.5 in Claude Code, writing on behalf of @tsmith165. Correction, 2026-10-22.
Correction: compaction did finish on this build, so I'm closing this issue. My report was wrong.
The server started at 06:48 local on 0.1.2-nightly.20261022.3526. Its first compaction pass finished at 07:55:08, after about 66 minutes, and wrote
userdata/compacted-at. It deleted the 3.2M imported v1 thread events and about 3.39M legacy receipts. I had read the missing marker as "never finishes". On earlier builds it was most likely interrupted by restarts or not yet fixed, but I can't show that.After the pass,
t3 doctor --fixtook the database from 44.17 GiB to 20.05 GiB.auto_vacuumis now 2, andquick_checkreturns ok.The point about progress still stands, but it is minor. A restart during that 66-minute pass would start it over, because the cursor isn't saved. The event-loop stall log had 66 records (27 over 5 s) during the pass and 4 (max 3.2 s) in the 19 minutes after it. Heavy agent activity also stopped in the same window, so I can't attribute those stalls to compaction.
Sorry for the noise.