Skip to content

🤖 feat: limit the CPU and memory that all local agent commands share - #6894

Open
ibetitsmike wants to merge 3 commits into
mainfrom
mike/agent-resource-limits
Open

ibetitsmike wants to merge 3 commits into
mainfrom
mike/agent-resource-limits

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Agents that run in parallel on one machine can use all of its CPU and memory and slow down everything else. This PR adds Settings → Agents → Resource limits: one CPU limit (cores) and one memory limit (GiB) that all local agent commands share, enforced with a Linux cgroup v2.

Resource limits, active

How it works

  • Xum uses the cgroup it runs in, which must be delegated to the user that runs Xum. On the first limit it moves its own processes into a child xum-app, enables the cpu and memory controllers, creates xum-agents, and writes cpu.max and memory.max.
  • LocalBaseRuntime.exec and the workspace init hook start each command with one shell line that moves the shell into xum-agents. If the move fails, the command still runs and prints one warning on stderr.
  • A probe command must land in xum-agents before the status says Active. Otherwise Settings shows the reason with Try again, and commands run without a limit.
  • The setting is agentResourceLimits in config.json. The server applies it at startup, on every config change, and on save. xum run and xum workflow apply it too. Settings follows changes made in another window or backend.
  • Not covered: terminals, the desktop of desktop tools, Xum itself, and Docker, dev container, SSH, and Coder workspaces. Docs: docs/config/agent-resource-limits.mdx.

Resource limits, not applied

Testing

  • Unit tests on a fake cgroup tree that follows the kernel rules this code depends on (EBUSY while the cgroup holds processes, PID moves), the enrollment line in real bash, LocalBaseRuntime, config parsing, and the Settings UI with changes made elsewhere, offline, and reconnect. src/cli/agentResourceLimits.test.ts runs xum run and xum workflow with a saved limit.
  • Real cgroup v2 (Linux 6.8, the docs' sudo recipe, a dev build of xum server): 8 busy loops used 2.51 cores under a 2.5 core limit, a Go 1.26 binary got GOMAXPROCS=3, and under 1 GiB a 2 GiB allocation was OOM-killed while the server kept running. Changing and clearing limits, a restart from xum-app, an init hook, and the "cannot manage" status behaved as documented.
  • After the round 1 fixes, on the same host: Settings in a browser followed limits that another client saved, without a reload, and kept the field that was being edited. Its fields were disabled while the server was down, and it showed the saved limits after the reconnect. xum workflow in a new delegated cgroup created xum-agents with the saved 1.25 cores and 1.5 GiB.
  • make static-check (hadolint is not installed locally), make lint-eslint, and make crap-check pass.

Risks

  • Xum's processes stay in xum-app after the limits are cleared.
  • Lowering the memory limit below current use can make the kernel OOM-kill agent processes.
  • Commands that started before the first limit keep running without it.

Review record

  • Codex round 1 (9acff81): five findings, each fixed with a test that failed before the fix.
    • P1 retry: unchanged limits are skipped only after a successful apply, so Try again in another backend also retries here.
    • P2 clear failure: reports "Could not remove the limits from the agent cgroup" with Try again, not "No limit is set".
    • P2 offline edits: inside Settings the Tasks fieldset already disabled the fields offline, and a reconnect already reloaded. The component now disables its own fields and Try again, refuses an offline save with the connection-lost message, and shows the saved limits after a reconnect.
    • P2 stale view: Settings reloads after each config change and keeps a field that is being edited. agentResourceLimits.get waits for queued applies, so the status matches the limits.
    • P1 headless roots: xum run and xum workflow start the limits service on the real config and dispose it on exit.
  • Codex round 2 (e41bb65): no findings, security review clean. CI then failed subscriptionInventory.test.ts, because the new config.onConfigChanged subscription had no restart rule. b6925ee adds it.
  • Codex round 3 (b6925ee): no findings, security review clean. Required passed on this commit.

Settings > Agents > Resource limits sets one CPU limit (cores) and one
memory limit (GiB) for all commands of local and worktree workspaces.
Xum enforces them with a cgroup v2 child (xum-agents) of the cgroup it
runs in, which must be delegated to the user that runs Xum. Each agent
shell joins xum-agents before its command runs; a failed move prints
one warning and the command runs without the limit. When the cgroup
cannot be managed, Settings shows why and commands run unlimited.
@mintlify

mintlify Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
Mux 🟢 Ready View Preview Oct 16, 2026, 10:24 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-16T22:38:36.562399Z b6925ee New commits
🔒 Security Review ✅ Completed 2026-10-16T22:39:05.739892Z b6925ee New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 9acff811fc

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9acff811fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/agentResourceLimits/agentResourceLimitsService.ts Outdated
Comment thread src/node/services/agentResourceLimits/agentCgroup.ts Outdated
Comment thread src/browser/features/Settings/Sections/AgentResourceLimitsSettings.tsx Outdated
Comment thread src/browser/features/Settings/Sections/AgentResourceLimitsSettings.tsx Outdated
Comment thread src/node/services/serviceContainer.ts
- The service applies unchanged limits again while they are not
  applied, so Try again in another backend's Settings retries here too.
  The warning logs once per new reason.
- A failure to remove the limits reports "Could not remove the limits
  from the agent cgroup" instead of "No limit is set".
- Settings follows config changes made elsewhere and keeps a field that
  is being edited. agentResourceLimits.get waits for queued applies.
- Settings disables its fields and Try again offline, refuses an
  offline save, and shows the saved limits after a reconnect.
- xum run and xum workflow apply the saved limits and dispose the
  service on exit.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: e41bb657f6

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: e41bb657f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Settings > Agents > Resource limits now subscribes to
config.onConfigChanged, so subscriptionInventory.test.ts needs a
restart rule for its file. A new client re-runs its effect; the live
client is now named api, which the effect-deps shape check looks for.

This branch was successfully deployed

1 active (outdated) deployment
staging - docs — e41bb657 Deployed Oct 16, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant