Summary
Bulk thread operations issue one command per thread, and every command rewrites the whole index, so cost grows with the square of the thread count.
Where
Store::upsert_meta / RemoveSession re-read and rewrite all of sessions.json (2 MB for ~2.7k threads on the maintainer's machine) for each change (crates/services/src/store.rs).
- Settings → Delete all archived sends one
DeleteSession per thread (the loop in crates/ui/src/settings_page.rs carries a "ponytail" note about exactly this), and each delete also calls persist_settings.
- Sidebar "Archive all" sends one
ArchiveSession per thread (crates/ui/src/sidebar.rs).
delete_project loops over delete_session; archive_session_ids persists each id of a subtree separately (crates/runtime/src/app/sessions.rs).
Proposal
- Protocol:
ArchiveSessions { session_ids }, UnarchiveSessions { session_ids }, DeleteSessions { session_ids, remove_worktrees }. Single-id commands become thin wrappers or are removed.
- Store writer:
UpsertMetas(Vec<SessionMeta>) and RemoveSessions(Vec<String>), one index write and one settings write per command.
- Cascades (archive subtree, delete subtree, delete project) use the batched writes.
This is independent of the storage-engine change and should land first; the redb index later makes each write cheap, but the batched command shape stays.
Summary
Bulk thread operations issue one command per thread, and every command rewrites the whole index, so cost grows with the square of the thread count.
Where
Store::upsert_meta/RemoveSessionre-read and rewrite all ofsessions.json(2 MB for ~2.7k threads on the maintainer's machine) for each change (crates/services/src/store.rs).DeleteSessionper thread (the loop incrates/ui/src/settings_page.rscarries a "ponytail" note about exactly this), and each delete also callspersist_settings.ArchiveSessionper thread (crates/ui/src/sidebar.rs).delete_projectloops overdelete_session;archive_session_idspersists each id of a subtree separately (crates/runtime/src/app/sessions.rs).Proposal
ArchiveSessions { session_ids },UnarchiveSessions { session_ids },DeleteSessions { session_ids, remove_worktrees }. Single-id commands become thin wrappers or are removed.UpsertMetas(Vec<SessionMeta>)andRemoveSessions(Vec<String>), one index write and one settings write per command.This is independent of the storage-engine change and should land first; the redb index later makes each write cheap, but the batched command shape stays.