Repository navigation
Description
What happened
T3 Code became unresponsive together with the other RAM-heavy applications on my Mac. In Activity Monitor the process showed 1.87 TB of virtual memory; how can that be?
The desktop app had been running for about 3 days with two Claude threads and three Codex delegated review tasks active. The Mac began swapping, the T3 Code main process stopped responding, and it had to be relaunched. The 1.87 TB virtual size turned out to be ordinary V8 address-space reservation (a freshly started server shows the same figure); the real signal was 2.3 MB resident, 32 KB private and "recent hangs: 36" on the main process.
Diagnosis
On macOS, agent commands run with no memory limit. apps/server/src/process/agentScope.ts (v0.1.0 line 112, and still on main) returns AgentScope.defaultValue() for every platform other than Linux, where agents get a systemd slice with MemoryHigh/MemoryMax. On a 16 GB Mac, two Claude threads plus Codex delegates whose children ran test suites and headless Chromium were enough to push the machine into heavy swapping. T3's own processes were then paged out: the embedded server logged rising major page faults and shrinking RSS for nine minutes, then the desktop main process went silent for 266 s with no quit record, no crash report and no OOM kill. Nothing in the app's logs records the hang itself (same gap as #21301).
The T3 process tree held about 2.5 GB of 8 GB resident after the restart, so T3 was both a contributor (uncapped agent children) and a victim of the swapping.
Steps to reproduce
Not deterministic. Observed once; no controlled repro was run.
- On a 16 GB Mac with other memory-heavy apps open, run the desktop app for a few days without restarting.
- Run two Claude threads in parallel and let one delegate review tasks to Codex; let the agents run test suites and headless browsers.
- When the Mac starts swapping, the T3 Code main process stops responding and leaves no record.
Version
0.1.0 (desktop app and embedded server; the t3 triage CLI was 0.1.2)
Environment
macOS 27.0.0, Apple Silicon, 16 GB RAM, desktop app with local server; Node v25.4.0 on PATH; claude 2.1.309; codex-cli 0.163.0
Evidence
# event-loop-stalls.ndjson (server), 2026-10-23 UTC. majorPageFaults rises, rssMb falls: the server is being swapped out.
{"time":"2026-10-23T08:38:11.899Z","delayMaxMs":5157,"utilization":0.31,"majorPageFaults":94,"minorPageFaults":70204,"rssMb":115}
{"time":"2026-10-23T08:38:41.905Z","delayMaxMs":3467,"utilization":0.19,"majorPageFaults":178,"minorPageFaults":49712,"rssMb":113}
{"time":"2026-10-23T08:45:12.020Z","delayMaxMs":2504,"utilization":0.28,"majorPageFaults":484,"minorPageFaults":64981,"rssMb":105}
{"time":"2026-10-23T08:46:23.045Z","delayMaxMs":2584,"utilization":0.35,"majorPageFaults":1610,"minorPageFaults":54595,"rssMb":59}
{"time":"2026-10-23T08:46:54.665Z","delayMaxMs":4927,"utilization":0.92,"majorPageFaults":3629,"minorPageFaults":95702,"rssMb":38}
{"time":"2026-10-23T08:47:27.315Z","delayMaxMs":5837,"utilization":0.82,"majorPageFaults":3937,"minorPageFaults":42547,"rssMb":184}
# desktop.trace.ndjson: main-process spans per minute, then a 266 s gap with no quit/shutdown span
08:44 290 08:45 183 08:46 171 [gap 08:46:49 -> 08:51:15, 266 s] 08:51 750 (desktop.startup after relaunch)
# renderer-history.ndjson: main renderer working set, same session (started 2026-10-20)
08:45:16 workingSetBytes 262848512 peakWorkingSetBytes 1258799104
08:46:56 workingSetBytes 9043968 peakWorkingSetBytes 1258799104 <- paged out
# Activity Monitor on the hung main process at 10:50:55 local
real 2.3 MB, virtual 1.87 TB, shared 61.3 MB, private 32 KB, CPU 0.00 %, recent hangs 36, parent launchd
# machine at triage time
vm.swapusage: total = 5120.00M used = 3943.00M free = 1177.00M
memory_pressure: Pageouts 151588 ; kern.memorystatus_vm_pressure_level: 1 (recovered after relaunch)
RSS under the T3 process tree after restart: 2483 MB of 8002 MB total
# source, v0.1.0 apps/server/src/process/agentScope.ts
111: const platform = yield* HostProcess.Platform;
112: if (platform !== "linux") return AgentScope.defaultValue();Related issues
#20329 is the same root cause (agent memory limits are Linux-only) but is closed as completed and locked, and the fix it refers to (#20330) was closed unmerged; this report adds a stable-release, 16 GB, low-concurrency data point. #21301 covers the missing hang record. #18485 is a Windows report attributed to MCP helpers under Codex.
Fix applied or workaround
Nothing changed on the machine. Workaround: relaunch the desktop app every day or two (the renderer had grown to 1.26 GB peak over 3 days), run fewer test-heavy threads at once, close other memory-heavy apps while agents run tests.
Filed by
Claude Fable 5.1 (claude-fable-5-1) in Claude Code, via t3 triage, on behalf of the user.
Activity
calebfender commentedon Oct 26, 2026
Another occurrence on 0.1.2 (stable desktop app, macOS 27.0 arm64, 16 GB RAM). This time it ended in a system-wide out-of-memory prompt, not just swapping.
What happened
One Claude thread (Opus 5.5) was doing disk forensics. It started an 8 GB Colima (VZ) VM, read blocks from a device-mapper snapshot of a full disk image inside it, and streamed a whole remote logical volume through
ssh … dd bs=16M | sha256sumin backgrounded subshells. At about 22:10Z macOS showed "Your system has run out of application memory". Force Quit listed T3 Code at 190.97 GB, so macOS was charging every agent child (the VM included) to the app. The user force-quit T3.T3's own processes were small just before this: the renderer working set was about 290 MB (
renderer-history.ndjson), and the server's lastevent-loop-stalls.ndjsonsample showsrssMb: 117, a 2.1 s delay and 685 major page faults. So nearly all of the footprint was uncapped agent children, which matches the diagnosis above.apps/server/src/process/agentScope.ts:96in v0.1.2 still returnsAgentScope.defaultValue()for every platform except Linux.Knock-on effect after the force quit
When the app was reopened at 22:11:00Z and again at 22:11:13Z, the backend exited with code 78 and
ServerAlreadyRunningError: A T3 Code server already owns <T3 home>, and the "This T3 home is unavailable" dialog appeared. The previous server's last trace entry is at 22:10:46Z, when it was still shutting down (closing OpenCode servers, stopping the relay client). By the time of triage it had exited, and nothing heldserver-owner.sqlite. This looks like the leftover-server case from #22983, reached through a force quit under memory pressure instead of Cmd-Q.Suggestion
Even without a cgroup equivalent on macOS, a per-thread watchdog on the agent process tree's footprint (warn, then stop the turn) would have stopped this before the OS did.
Filed via
t3 triageby Claude Code (Opus 5.5,claude-opus-5-5).calebfender commentedon Oct 26, 2026