[Windows Desktop] git write-tree polling loop causes ~26% idle CPU (non-Git workspaces + bloated .git/objects)
Summary
Codex Desktop on Windows runs a high-frequency git write-tree polling loop for workspace change detection. When a workspace directory is either (a) not a Git repository, or (b) a Git repo with severely bloated .git/objects, this loop becomes a CPU spin that consumes ~26% idle CPU continuously.
Environment
- OS: Windows 10
- Codex: OpenAI.Codex 26.623.19656.0 (Microsoft Store / UWP)
- Git: 2.x (system git at
D:\Program Files\Git\cmd\git.exe)
Root Cause
Codex appears to call git write-tree at high frequency (observed: 10 new git.exe processes in 10 seconds) to compute tree hashes for workspace change detection.
Two failure modes trigger the CPU spin:
1. Non-Git workspace directory → fatal retry loop
When the active workspace is not a Git repository, git write-tree returns fatal: not a git repository (exit 128). Codex appears to immediately retry, creating a tight failure-retry loop.
Reproduction:
# Set a non-Git directory as Codex workspace, then observe:
$seen=@{}; $t0=Get-Date
while((Get-Date) -lt $t0.AddSeconds(10)){
Get-Process -Name "git" -ErrorAction SilentlyContinue | ForEach-Object {
if(-not $seen.ContainsKey($_.Id)){ $seen[$_.Id]=1 }
}
Start-Sleep -Milliseconds 500
}
Write-Host "git processes spawned in 10s: $($seen.Count)"
# Result: 10+ processes, all running: git -c core.hooksPath=NUL -c core.fsmonitor= write-tree
2. Git repo with bloated .git/objects → slow operations × high frequency
A workspace repo with 6,086 unreachable loose objects (675 MB, from repeated git add of large files without committing) makes each git write-tree invocation extremely slow. Combined with the high polling frequency, CPU saturates.
Impact
- Idle CPU: ~26% sustained (8-core machine), no active task running
- Fan/heat: continuous fan activity with no workload
- System becomes sluggish even when Codex is idle
Evidence
# git process spawn monitoring (10s window)
git processes spawned in 10s: 10
# Command line of spawned git processes
"C:\...\git.exe" -c core.hooksPath=NUL -c core.fsmonitor= write-tree
Parent: Codex.exe (main process, PID 22024)
# CPU before fix
Average CPU usage: 18.42% (sustained, idle)
# .git/objects bloat in active workspace
loose objects: 6086, 675.47 MB
largest objects: 155MB, 155MB, 48MB, 27MB, 11MB
Workaround
- For non-Git workspace dirs: run
git init(even an empty repo makeswrite-treereturn successfully instead of fatal) - For bloated repos: run
git gc --prune=now --aggressiveto remove unreachable objects - Secondary: clean
logs_2.sqlite(232MB, related issue #31142) and old desktop logs
After workaround, idle CPU dropped from ~26% to 0.06%.
Suggested Fixes
- Add a timeout or backoff for
git write-treefailures (non-Git directories should not cause a tight retry loop) - Detect non-Git workspaces and skip git-based change detection (fall back to filesystem watcher or polling)
- Limit git operation frequency when the previous invocation was slow (e.g., if write-tree takes >2s, increase the polling interval)
- Auto-prune or warn when
.git/objectsexceeds a size threshold
Related Issues
- #31142 —
logs_2.sqlitehigh-frequency WAL writes (secondary I/O contributor in this case) - #31132 — Log level not configurable, sqlite grows to 1.4GB
Full Diagnostic Manual
A complete troubleshooting manual (detection methods, root cause analysis, fix scripts, prevention) is available at:
https://github.com/cngh0/codex-cpu-fix
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Additional Windows 11 reproduction on the current Desktop release.
Environment
26.707.3748.00.144.126200, x64C:\Program Files\Git\cmd\git.exeNew runtime evidence
The active workspace was a normal directory with no
.gitpath at all. While the Codex Desktop window and turn were active, I sampled processes whose direct parent was the packaged DesktopChatGPT.exeprocess.git.exePIDs in 12 seconds.git.exePIDs in a denser 6-second sample.git.exePIDs.The short-lived processes often exited before their command line could be read, so the PID count is higher than the number of captured command strings.
This confirms that the failure-retry behavior is not limited to a repository with bloated objects: a workspace with no
.gitdirectory can drive repeated Git root discovery at roughly 3-5 process starts per second. The Git processes were direct children of the packaged Desktop process, not of a shell command launched by the user.Suggested guardrail
Cache the non-repository result per workspace and apply exponential backoff after
rev-parse --show-toplevelfails. A new filesystem event or explicit workspace refresh can invalidate the negative cache. At minimum, avoid overlapping probes and suppress repeated process creation while the previous result is unchanged.---
This issue or PR was generated by LazyCodex.
Tag: lazycodex-generated
The idle
git write-treepolling loop here is the same class of Git-backed refresh workload that this workaround disables.I published a single-file Windows launcher for the original Microsoft Store/MSIX Codex app:
It starts Codex with a process-scoped
GIT_DIR=NUL. On my machine, the stable trace changed from 247 newgit.exeand 137 newtaskkill.exeprocesses per 10 seconds to 0 and 0 over 15 seconds; WMI Provider Host fell from about 6.6% to 0.9%.Usage: fully exit Codex from the Windows system tray, then run the script.
This is an unofficial workaround, not an upstream fix. It deliberately disables or limits Review, Changes, branch detection, commit, and other Git-backed Codex features. It does not patch Codex, modify repositories or Git configuration, write system environment variables, require elevation, terminate processes, or remove chat history. Launching Codex normally restores Git integration.