Repository navigation
When agents keep memory pressure high, stop one agent's command instead of stalling every agent #21288
josephv123
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Note
Claude Opus 5.5 in Claude Code, writing on behalf of @josephv123. Measured on his machines on 2026-10-18.
Problem
When several agents run heavy commands at once (test suites, typechecks, browsers), their combined memory can exceed what the machine has. Today nothing resolves that state; it just lasts.
app-t3code-agents.slicewithMemoryHigh = max(RAM − 6 GB, RAM / 2)andMemoryMax = max(RAM − 4 GB, 0.75 × RAM)(fix(server): agents run in their own systemd scopes so an OOM kill spares the server #17662,apps/server/src/process/agentScope.ts). [Bug]: Sustained agent MemoryHigh stalls and WSL reconnecting during parallel dependency installs, without an OOM kill #18350's triage confirmed that throttling atMemoryHighwithout an OOM kill is intended, so the server stays up. It does stay up. But on a host with swap or zram, reclaim keeps "succeeding" by pushing pages out. The slice never reachesMemoryMax, nothing is killed, and every agent in it stalls together, including the thread the user is watching.#18350's triage asked for configurable thresholds and a pressure indicator in Ideas. #20330 (an opt-in macOS memory guard) was closed because stopping commands under memory pressure needs maintainer agreement first. This discussion asks for that agreement, with measurements.
Measurements
Nightly
0.1.1-nightly.20261018.3315, Claude Code 2.1.302, Claude Haiku 5.5. Every agent was a real T3 thread created through the server API, in its own worktree of this repo. Each one:packages/sharedandapps/server(thetsc-rsstep peaks at about 3–4 GB),All tests were re-verified afterwards.
Linux: Ryzen 7 8840HS, 12.9 GiB RAM, zram 2 × 6.4 GiB plus a 4 GiB swap file,
vm.swappiness=150. Slice: 6.9 GiB high, 9.7 GiB max, no swap limit.With the raised limits, the other 5 agents' scopes were OOM-killed within the first two minutes, and systemd recorded each scope's result as
oom-kill. So 5 failed agents and 7 that finished, instead of twelve stalled agents.Slice counters at the end of the day (cumulative over all runs):
memory.events high18,059,597 andmax0memory.pressurefull total 1,930 s (32 minutes in which every task in the slice was stalled)memory.peak9.9 GB, withmemory.swap.peak17.2 GB on topOn the same host, a replay of a similar tool mix outside the slice, with no model, kept running at 16 agents at once and only hit a kernel OOM at 20. So the stall comes from how the limit behaves, not from the hardware.
Linux: Ryzen 7 4700U, 7.1 GiB, zram. Slice: 3.8 / 5.7 GB.
macOS: M5, 16 GB, with the user's usual apps open (about 11 GB used before agents started).
kern.memorystatus_vm_pressure_levelstayed at 4 (critical). The desktop app's main process hung and had to be force-quit, and SSH stopped answering.Why the Linux limit doesn't end it
memory.high, every task in the slice reclaims on each allocation and then sleeps as a penalty. The kernel never OOM-kills athigh; its documentation pairshighwith an outside monitor that acts on pressure.memory.maxis never hit. zram's compressed pages also live in RAM without being charged to the slice, so the intended "6 GB left for the system" isn't actually reserved.Proposal (asking which direction you'd accept)
The goal stays that of #17662: the server and SSH survive. The change: when pressure is sustained, end it by stopping one agent's command, rather than slowing every agent indefinitely. Possible pieces, smallest first:
MemorySwapMax, e.g. half of swap). Sustained overcommit then reachesMemoryMax, and the kernel kills one scope, whichOOMPolicy=stopalready reports in the thread.fullabove 40% for 30 s, stop the largest background agent command, or hold new turn starts until pressure drops, and tell the affected thread. This is the behavior fix(server): opt-in memory guard keeps parallel test runs from crashing macOS #20330 implemented for macOS, and it would give feat(diagnostics): identify the agents and exec commands behind sustained CPU or memory load #15449 a concrete signal to show.oom_score_adjthan background agents' 800. In a global OOM caused outside T3 today, the kernel's first victim was the interactive Claude session (39 MB anonymous RSS,oom_score_adj800). Killing it freed almost nothing.Which of these, if any, would you take as focused PRs? Joseph can re-run the same three-machine benchmark against any candidate.
Related: #17662, #18350, #20329, #20330, #15449, #20038 (WIP cap).
All reactions