{"version":"2.1.246","anchor":"tool-subprocesses-can-be-launched-inside-a-memory-capped-cgr","canonical_anchor":"tool-subprocesses-can-be-launched-inside-a-memory-capped-cgr","heading":"Tool subprocesses can be launched inside a memory-capped cgroup","tier":"soon","area":"Sandbox","scope":null,"heads_up":null,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.246\/e\/tool-subprocesses-can-be-launched-inside-a-memory-capped-cgr","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.246","markdown":"### Tool subprocesses can be launched inside a memory-capped cgroup\n\nMCP servers, hooks, plugin installs and tmux sessions can run under a memory cap, dark-launched here.\n\n**What**\n\nOn Linux and WSL, child processes started by Claude Code can now be placed into a memory-limited control group, so a runaway server or hook is killed at a cap instead of exhausting the host. This covers stdio MCP servers, LSP servers, hook runners, plugin installs, tmux agent sessions and the background terminal host, all launched through a wrapper that joins the capped group before running the real command. None of it is active in this build: the exclusion list falls back to a set containing every one of those classes, so the wiring is dark-launched unless `CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDE` or server config says otherwise.\n\n**Details**\n\n- The two shared process-spawning helpers now accept `useToolMemoryCgroup` and `toolCgroupClass` options, and plugin subprocesses pass the `plugin` class.\n- A process started before the cgroup is ready has its process id parked and is adopted into the group once the group exists, rather than being lost track of.\n- MCP capping has its own switch, `CLAUDE_CODE_MCP_MEMORY_CGROUP` or failing that the `tengu_mcp_memory_cgroup` setting; only an explicit false opts out, and when it resolves to disabled MCP is added to the exclusion list and no MCP server is capped.\n- Each MCP server process is registered against the cgroup by process id together with its start time read from \/proc, rechecked whenever the set of hooks changes, so a stale process id cannot be mistaken for a live server.\n- A capped MCP server is released from the cap just before a hook backed by that server fires, so the hook does not run against a constrained process; a fixed set of events skips this release path, including Notification, SessionStart, SessionEnd, Setup and StopFailure.\n- Claude Code's own helpers deliberately opt out with `useToolMemoryCgroup: !1`: npm update checks, the Linux clipboard helpers, the CA installer, AWS credential export, systemctl, xdg-open and \"open project in IDE\".\n- The external editor launch and the terminal host retry the spawn without the cgroup if the first attempt fails.\n- When an LSP server dies by SIGKILL or exit 137 while capped, the crash message names the cause by appending ` killed at the tool memory limit (CLAUDE_CODE_TOOL_MEMORY_LIMIT)`, or says \"likely killed\" when it cannot confirm the cause.\n- If the host has too little memory for the default cap, the feature disables itself and logs `tool cgroup: disabled (host too small for the default cap)`; the `tool cgroup:` log lines are all new in this build.\n\n**Evidence**\n\n`{ echo 0 > \"$0\"\/cgroup.procs; } 2>\/dev\/null; exec \"$@\"`, `toolCgroupClass`, `useToolMemoryCgroup: !1`, `useToolMemoryCgroup`, `tool cgroup: disabled (host too small for the default cap)`, `killed at the tool memory limit (CLAUDE_CODE_TOOL_MEMORY_LIMIT)`, `hook was still capped at fire time`, `let { useToolMemoryCgroup: r, toolCgroupClass: o, ...i } = n,`\n\n- Flag `tengu_mcp_memory_cgroup`: Off in both readings (read for one account on one subscription tier against v2.1.246; this account: off, anonymous baseline: off, compiled default: not a boolean we can read)\n- Area: Sandbox\n- Names: `CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDE`\n- Tier: Nothing to try yet\n- Useful: 3\/5\n- Signal: 4\/5\n- Present in the build but not switched on"}