Why Codex on Windows gets slow with WSL: measured EISDIR retries and MCP growth¶
For / Key Points
For: Developers investigating sustained CPU and memory growth when Codex on Windows opens a Git repository stored in WSL2.
Key Points:
- The latest 80 logs on one machine contained 341,602
EISDIRentries - WSL retained 22 MCP processes using about 1.28 GB of aggregate RSS
- Windows-side watcher retries and per-chat MCP retention need separate mitigations
Codex on Windows became progressively less responsive while working with a repository stored in WSL2. The first suspect was WSL I/O, but the logs showed repeated Git-path watcher failures while WSL retained MCP (Model Context Protocol) processes for opened chats.
There was no single source of the slowdown. Following the Windows file-watcher loop separately from WSL-side MCP runtime retention explains why CPU, logs, and memory grew together.
Test environment and scope¶
The numbers were collected on July 14, 2026 from the PC while the slowdown was active. The OS and version details remain for reproducibility; only usernames, repository names, and task identifiers were redacted.
| Item | Value |
|---|---|
| OS | Windows 11 x64 |
| Codex Windows app | 26.707.9981.0 |
| App agent mode | WSL mode |
| Codex CLI inside WSL | 0.144.4 |
| WSL | WSL2 / Ubuntu 26.04 |
| Repository location | Linux filesystem inside WSL |
| Path seen by Windows | \\wsl$\Ubuntu-26.04\home\<user>\<repository> |
OpenAI's documentation describes a mode that runs the Windows app's agent in WSL21. This machine was already using that WSL mode. The important result is that Windows-side Git monitoring and WSL-side MCP retention still coexisted.
Get-Location, Get-Date, and simple string output still completed in about 0.2 to 0.3 seconds. Trivial commands did not freeze for minutes. The evidence here covers sustained background load, not every form of Codex latency.
Cause 1: EISDIR watcher retries on a WSL Git path¶
The first load source was Windows-side Git workspace monitoring. Codex logs repeatedly showed a watcher failing against the .git directory in WSL.
[git-repo-watcher] Failed to watch git path
errorCode=EISDIR
errorMessage="EISDIR: illegal operation on a directory,
watch '\\\\wsl$\\Ubuntu-26.04\\home\\<user>\\<repository>\\.git'"
EISDIR indicates that an operation could not proceed because its target was a directory. On this machine, a Windows-side Node.js watcher failed against the WSL Git path.
More than 341,000 entries in the latest 80 logs¶
Scanning the latest 80 log files showed an unusually dense repetition of the same error family.
| Pattern | Matches |
|---|---|
EISDIR | 341,602 |
git-repo-watcher | 341,874 |
git-init-watcher | 387 |
Several July 14 logs contained about 9,000 EISDIR entries each and rotated at roughly 10 MB. Another log from July 13 placed git-init-watcher failures at approximately five-second intervals.
The interval and error shape match openai/codex issue #326952. That issue documents Windows 11 and WSL2 watcher failures continuing at about five-second intervals and was open on July 14, 2026. The locally measured build was newer than the reported build, so the same error family was still present in 26.707.9981.0.
The central problem is not merely the log volume. A permanent watcher error keeps being retried while the app remains open. Deleting logs cannot prevent the next write.
Cause 2: MCP processes retained for opened chats¶
The second load source was the MCP process tree owned by the WSL app-server. Multiple generations of the app-managed node_repl MCP remained under one app-server.
| Item | Measured value |
|---|---|
| Total MCP processes | 22 |
server.cjs | 11 |
server.mjs | 11 |
| Aggregate MCP RSS | About 1,283 MB |
| WSL app-server | About 337 MB |
The processes had different elapsed times, so they were not one batch started at the same moment. Their ages were consistent with new MCP pairs appearing as chats were opened while previous pairs remained alive.
Issue #32154 reports a Windows/WSL2 environment in which switching to each previously unloaded chat started another MCP process generation3. Its control test reduced retained MCP RSS by about 96% after user-configured stdio MCP servers were disabled, but the desktop UI stall remained. MCP memory amplification and chat-navigation cost can therefore overlap without being the same failure.
All 22 processes in this measurement belonged to the app-managed node_repl, not user-added MCP servers. It would be inaccurate to promise that disabling external MCP servers fixes this case. Moving the workflow outside the Windows app and limiting simultaneously loaded chats are safer first steps than deleting managed configuration.
CPU and log-storage impact¶
The Windows Codex process family consumed about one logical processor during short samples. CPU time increased by about 3.08 seconds over a three-second window and by about 5.64 seconds in a separate five-second window.
These were snapshots, not controlled idle benchmarks. A rigorous attribution would compare the same machine immediately after restart, after opening the WSL project, and after reducing MCP load.
The log-storage effect was easier to quantify.
| Scope | Size |
|---|---|
| All Codex logs | About 474 MB |
| July 14 logs | About 137 MB |
| July 14 log files | 21 |
It would be premature to connect all three measurements into one causal chain. CPU, logs, and MCP memory grew in the same environment, but no single measurement was proven to cause the other two. The evidence establishes that watcher retries and MCP retention coexisted.
A five-minute diagnostic¶
Check the Windows logs and the WSL process tree separately. The commands below reveal the error family and process count without publishing the real username or repository path.
Search Windows logs for watcher errors¶
In PowerShell, narrow the input to recent logs and search for the three watcher patterns.
$pkg = Get-AppxPackage OpenAI.Codex
$root = Join-Path $env:LOCALAPPDATA `
"Packages\$($pkg.PackageFamilyName)\LocalCache\Local\Codex\Logs"
$files = Get-ChildItem $root -Recurse -File |
Sort-Object LastWriteTime -Descending |
Select-Object -First 30
Select-String -Path $files.FullName `
-Pattern 'EISDIR|git-init-watcher|git-repo-watcher'
A handful of entries may be transient. If the same path accumulates errors every few seconds, suspect an active retry loop.
Count MCP generations inside WSL¶
Inspect parent PIDs, RSS, and elapsed time for the app-server and Node processes.
wsl -d Ubuntu-26.04 -- bash -lc `
"ps -eo pid,ppid,%cpu,%mem,rss,etime,cmd --sort=-rss |
rg -i 'codex|mcp|node' | head -50"
Repeated command lines with elapsed times matching chat switches point toward per-chat retention. Record the parent PID and aggregate RSS as well as the process count so that before-and-after comparisons remain meaningful.
Remove the Windows app's watcher path¶
This machine was already in WSL mode, so changing the agent selector alone was not a remedy. The next target is the Windows app's management of the workspace through \\wsl$.
1. Use Codex CLI natively inside WSL¶
For a workflow that keeps the repository and runtime entirely on the Linux side, start Codex CLI from a WSL shell. OpenAI's WSL guide likewise shows repositories under the Linux home directory and codex running inside WSL4.
This path removes the Windows app's \\wsl$ watcher from the active workflow. When watcher retries and MCP retention continue in WSL mode, it is the most direct workaround if the desktop UI is optional.
2. If the GUI is required, use a Windows-native clone¶
To keep using the Windows app, clone the repository into a path such as C:\src\... and use the Windows-native agent. OpenAI's documentation also recommends Windows-side project storage when the Windows-native agent remains in use1.
WSL can still access that copy through /mnt/c/... when necessary. If the project depends on a Linux-native toolchain, prefer the CLI path instead.
Mapping \\wsl$ to a drive letter does not change the underlying watcher target. Issue #32695 also reproduces through a mapped drive, so a drive letter is not a reliable workaround2.
3. Minimize loaded chats and stdio MCP servers¶
Opening several existing chats can increase the number of retained runtimes. Avoid browsing through unused chats, and fully quit the app when load grows so that process cleanup can be verified.
Disable only unnecessary user-configured stdio MCP servers. When app-managed helpers dominate the process tree, try a CLI workflow outside the Windows app before editing or deleting managed configuration.
Measures unlikely to address the cause¶
The following changes may lower a number temporarily while leaving the load-producing path in place.
- Deleting logs only: Recovers disk space but leaves the watcher retry active
- Lowering the WSL memory cap only: Does not reduce the number of MCP processes
- Mapping the WSL path to a drive: Does not change how the WSL target is watched
- Reinstalling only Codex CLI: Does not update the app's bundled app-server behavior
- Attributing every delay to these issues: Minute-long freezes and fixed per-command latency were not reproduced here
A product-level fix needs to stop retrying permanent watcher errors and release MCP runtimes when inactive chats no longer need them. Until then, users can reduce the OS boundary and the number of concurrently loaded chats.
Summary¶
This environment showed an EISDIR watcher loop and per-chat MCP retention at the same time. The former primarily inflated Windows-side CPU and logs; the latter inflated WSL process count and memory.
Use this order of operations:
- Run Codex CLI natively inside WSL for repositories stored in WSL
- If the GUI is required, clone the repository to Windows and use the Windows-native agent
- Minimize existing chats and stdio MCP servers, then measure again
The easy detail to miss is that the desktop chat list is not always just presentation state. When each loaded chat owns an MCP runtime, the loaded-chat count becomes a process and memory budget. Track log matches, parent-child process relationships, and RSS together to catch the next recurrence early.
Related Articles¶
- Fix Codex App database is locked in WSL mode
- Codex and Codex CLI Complete Guide
- How to read Codex CLI diagnostic logs
ChatGPT desktop app for Windows: Windows Subsystem for Linux - OpenAI ↩↩
[App/Windows/WSL] git-init-watcher retries permanent EISDIR on workspace root every five seconds - openai/codex #32695 ↩↩
Windows/WSL2: Desktop retains one eager MCP stack per opened chat and replays history during navigation - openai/codex #32154 ↩