Before submitting
Area
apps/server
Steps to reproduce
- Run the server (
t3 serve) and keep it up for an extended session (many hours), using several concurrent threads and creating/archiving/deleting threads over time.
- Watch the server process RSS and CPU time (for example with
ps/htop), and watch the web UI responsiveness.
- Compare a freshly started server against one that has been up for 12+ hours with the same workload.
Observed on a real server: the process reached roughly 1 GB RSS with hundreds of minutes of accumulated CPU time, and the web UI became progressively laggy the longer the server stayed up.
Expected behavior
Steady-state memory and per-event CPU should stay roughly flat over uptime. Command processing cost should not scale with the total number of threads ever created, and deleted threads should not keep costing work forever.
Actual behavior
The in-memory orchestration command read model stores threads and projects as arrays. Every domain event runs an O(N) linear .find() over the threads array and produces a full-array .map() copy through the projector, so per-event work and allocation scale with the total thread count. Deleted and archived threads are never removed from the model (only timestamped), so N grows monotonically for the life of the process and every subsequent event gets slower, increasing GC pressure.
Two client-side contributors compound this in long-lived browser tabs:
- Several per-thread stores (preview state, right panel, diff panel, ui state) accumulate one entry per thread ever visited and are never pruned on thread deletion; the ready-made cleanup functions exist but are not wired into the delete flow.
previewStateAtom is keepAlive, so its atoms are retained for the tab lifetime.
- The
VcsStatusBroadcaster per-cwd status cache is never pruned; it grows one entry per distinct cwd for the life of the server process.
Impact
Major degradation or frequent failure
Version or commit
main @ 2640e6d
Environment
Linux server (t3 serve), Node 24; reproduced with multiple concurrent threads over long uptime.
Workaround
Restarting the server clears the in-memory model and temporarily restores responsiveness, but the growth returns over time.
Before submitting
Area
apps/server
Steps to reproduce
t3 serve) and keep it up for an extended session (many hours), using several concurrent threads and creating/archiving/deleting threads over time.ps/htop), and watch the web UI responsiveness.Observed on a real server: the process reached roughly 1 GB RSS with hundreds of minutes of accumulated CPU time, and the web UI became progressively laggy the longer the server stayed up.
Expected behavior
Steady-state memory and per-event CPU should stay roughly flat over uptime. Command processing cost should not scale with the total number of threads ever created, and deleted threads should not keep costing work forever.
Actual behavior
The in-memory orchestration command read model stores
threadsandprojectsas arrays. Every domain event runs an O(N) linear.find()over the threads array and produces a full-array.map()copy through the projector, so per-event work and allocation scale with the total thread count. Deleted and archived threads are never removed from the model (only timestamped), so N grows monotonically for the life of the process and every subsequent event gets slower, increasing GC pressure.Two client-side contributors compound this in long-lived browser tabs:
previewStateAtomiskeepAlive, so its atoms are retained for the tab lifetime.VcsStatusBroadcasterper-cwd status cache is never pruned; it grows one entry per distinct cwd for the life of the server process.Impact
Major degradation or frequent failure
Version or commit
main @ 2640e6d
Environment
Linux server (
t3 serve), Node 24; reproduced with multiple concurrent threads over long uptime.Workaround
Restarting the server clears the in-memory model and temporarily restores responsiveness, but the growth returns over time.