Skip to content

Codex Desktop (macOS): source-control watcher spawns thousands of git/sec on workspaces containing embedded git repos → syspolicyd/trustd CPU storm, fans max #29084

Open

Description

@0xtootoo29

Summary

On macOS, the Codex desktop app's source-control integration runs git status continuously (file-watcher driven). When the open workspace contains embedded/nested git repositories (other repos cloned into a tracked parent repo — recorded as gitlinks, not proper submodules), the watcher recurses into every embedded repo and spawns thousands of short-lived git processes per second (≈4000/s with 18 embedded repos here). On macOS each git exec triggers Gatekeeper code-signature validation, so syspolicyd (~180%) and trustd (~100%) peg the CPU — fans max, system-wide beach-balls — while Codex's own process CPU stays low, which makes it look like a "GPU/rendering" problem.

Smoking gun / negative controls:

  • The codex CLI is unaffected (no continuous SCM watcher) → it's the desktop watcher, not git or the model.
  • A fresh/empty workspace is fine; only workspaces containing embedded repos trigger it.
  • git config diff.ignoreSubmodules all on the workspace drops git to 0/s and syspolicyd to ~5% → confirms the recursion-into-embedded-repos path is the cause.

Environment

Codex Desktop observed on 26.611.62324; since auto-updated to 26.616.32156 (repro is version-agnostic)
Platform macOS 26.5.1 (25F80), Apple Silicon — Darwin 25.5.0 arm64
Display Built-in Liquid Retina XDR (ProMotion 120 Hz)
Model / Plan gpt-5.5 / ChatGPT subscription (official login)
git 2.50.1 (Apple Git-155)
Workspace 41 GB repo with 18 embedded git repos (gitlinks, mode 160000, no .gitmodules)

Steps to reproduce (minimal, version-agnostic)

# 1) A git repo that contains a few embedded git repos
D=/tmp/codex-nested-demo; mkdir -p "$D"; git -C "$D" init -q
echo root > "$D/root.txt"; git -C "$D" add . && git -C "$D" commit -qm init
for d in nested-a nested-b nested-c; do
  mkdir -p "$D/$d"; git -C "$D/$d" init -q; echo x > "$D/$d/x.txt"
  git -C "$D/$d" add . && git -C "$D/$d" commit -qm init
  git -C "$D" add "$d"   # git warns: "adding embedded git repository" — creates the gitlink
done
git -C "$D" commit -qm "add nested repos"

# 2) Open  /tmp/codex-nested-demo  as the workspace in Codex Desktop.
# 3) Watch git spawn rate from any terminal:
for i in $(seq 1 10); do echo "git procs: $(pgrep -x git | wc -l)"; sleep 0.3; done
#    -> stays continuously high (thousands/s with more embedded repos)
# 4) macOS `top`: syspolicyd ~180%, trustd ~100%; fans ramp.

Real-world trigger: this happens naturally when you git clone projects into a folder that is itself a git repo — git records each as a gitlink (see its own warning above).

Expected vs actual

  • Expected: the SCM watcher polls git status at a bounded rate and does not dive into every embedded repo; CPU near-idle when not editing.
  • Actual: unbounded git spawning (~4000/s) → syspolicyd/trustd CPU storm, fans, global lag.

Impact

Opening any large / monorepo-style workspace that contains nested git repos (common: a projects folder, vendored clones, tool checkouts) causes sustained 100%+ system CPU, thermal throttling, battery drain, and beach-balls across all apps — easily misread as a GPU issue since the Codex process itself looks idle.

Local diagnostics

  • pgrep -x git | wc -l → ~4000/s; lsof -d cwd <git-pid> → all running in the workspace root.
  • top: syspolicyd ~180%, trustd ~100%, WindowServer high; quitting Codex → ~0.
  • /usr/bin/sample <Codex pid> → main thread in V8/JS + uv__fsevents (libuv file-watch).
  • A single git status on the workspace is ~0.18 s → the problem is spawn rate × N embedded repos, not slow git.

Root-cause hypothesis

The desktop SCM watcher re-runs git status (incl. per-submodule status) on a tight, file-event-driven loop with no debounce and no embedded-repo/depth guard. With N embedded gitlinks it spawns ≥N git children each pass; on macOS the per-exec Gatekeeper validation turns that into a syspolicyd/trustd storm.

Workaround (confirmed)

On the workspace repo: git config diff.ignoreSubmodules all (+ git config core.untrackedCache true) → git 0/s, syspolicyd ~5%. Cleaner structural fix: untrack the embedded repos (git rm --cached <dir>) and .gitignore them so they stay independent repos the parent ignores.

Suggested direction

  • Debounce/coalesce the SCM git status polling; cap concurrent git children.
  • Don't recurse into embedded/nested repos for status; honor diff.ignoreSubmodules.
  • Add a scan-depth / exclude setting (prior art: VS Code git.repositoryScanMaxDepth).

Related (searched, appears distinct)

#27570 / #27382 (nested repos, different code paths) and #11524 (macOS git→syspolicyd, venv trigger) — filing the macOS desktop SCM-watcher + embedded-repo + syspolicyd combination as a distinct, instrumented report.

Activity

  1. 0xtootoo29 commented on Jun 19, 2026

    @0xtootoo29
    Author

    Thanks — I checked the two flagged issues (#27570, #27382). They share the same trigger (a workspace containing nested/embedded git repos), but the mechanism and symptom differ, so this looks like a distinct manifestation rather than a duplicate:

    These all look like facets of "the git worker doesn't bound work across nested repos", so I'm happy to consolidate or close in favor of a single root-cause issue if the team prefers to track them together — just flagging the distinct code path, the macOS validation-storm symptom, and the workaround in case they're useful. 🙏

  2. VMescheryakov commented on Jun 26, 2026

    @VMescheryakov

    This should be treated as blocker severity for Codex Desktop.

    Reason:
    Codex Desktop is a coding agent whose primary workflow is opening Git workspaces. In affected workspaces, the app continuously spawns git.exe / git processes in the background while idle. On Windows, every spawned git.exe and the files it touches are inspected by Defender/corporate AV; on macOS, each git spawn can trigger Gatekeeper/code-signature checks via syspolicyd/trustd. This turns a background SCM watcher into a system-wide CPU/I/O storm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingperformance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions