Second data point, macOS, build of main ac8dce0cc3 (v0.1.6), one heavy user, ~11 weeks of history.
statev2.sqlitewas 15.06 GB;VACUUM INTObrought it to 9.74 GB. The 4.6 GB freelist came from the 6-hourly event compaction (#21154): it deletes superseded events, but on a database created beforeauto_vacuum=INCREMENTALbecame the default, nothing hands those pages back. After the vacuum (withauto_vacuum=INCREMENTAL),DatabaseStorage.reclaimkeeps the freelist at 0.- Live data still grows about 1.5 GB a week. Over the week before the vacuum,
page_countstayed at 3,676,931 while 357k free pages were reused. dbstaton the 15 GB file:orchestration_events4.7 GB (1.07M rows) plus 1.1 GB of event indexes;orchestration_v2_projection_turn_items2.1 GB;orchestration_v2_projection_nodes0.9 GB.- Event payload bytes:
turn-item.updated1.86 GB,node.updated0.69 GB,provider-turn.updated0.15 GB. Compaction keeps the first and the latestturn-item.updatedfor each item, so a finished tool call's output is stored twice: in the projection row and in the latest event. - The largest single category is Pi
readtool output: 660 MB in turn items. Of that, 325 MB is 961 image reads (base64 PNG screenshots, up to 3.8 MB each), and the events hold the same ~331 MB again. - By thread origin: delegated-task child threads hold 55% of event bytes, MCP-launched threads 26% and user threads 19%.
Retention that would bound this for us while keeping settled and archived history readable: purge deleted threads (#17845); once a thread is settled, drop the item events whose final state the projection rows already hold; and store large tool-output and image blobs once, by reference, instead of inline in both the event and the projection.