Codex desktop exhausts the Linux file-watch limit by watching .venv, cache, and Git-internal files
What version of the Codex App are you using (From “About Codex” dialog)?
26.814.41957
What subscription do you have?
ChatGPT Pro
What platform is your computer?
Ubuntu 26.04 LTS (Resolute Raccoon), Linux kernel 7.0.0-30-generic, x86_64
What issue are you seeing?
When I use Codex desktop with several local repositories, the ChatGPT process consumes nearly the entire Linux inotify file-watch allowance.
On my computer, ChatGPT owned 65,082 watches while the system limit was 65,536. This prevents other applications from creating file watches and can stop them from opening or monitoring projects correctly.
Codex’s git-repo-watcher is watching large numbers of files that should normally be excluded, including:
- Repository .venv dependencies
- __pycache__ directories
- .git/objects
- .git/refs/codex/turn-diffs
- Files inside Git submodules
- Generated and cached files
The logs repeatedly report:
ENOSPC: System limit for number of file watchers reached
I also recorded 118 “Starting git repo watcher” events within approximately 20 minutes.
I have not proven that completed tasks leave stale watches behind. The confirmed problem is that each watcher covers far too many unnecessary files.
What steps can reproduce the bug?
Use Codex desktop on Linux with several local repositories.
Have ordinary Python virtual environments inside the repositories, such as .venv.
Open several Codex tasks across different repositories.
Run longer tasks, including tasks that use agents or sub-agents.
Leave Codex open and move between these tasks for approximately 20 minutes.
Check the Linux watch limit:
sysctl fs.inotify.max_user_watches
Count the watches owned by the main ChatGPT process:
pid=$(pgrep -o -f '/usr/lib/chatgpt/ChatGPT')
grep -h '^inotify' /proc/$pid/fdinfo/* | wc -l
Inspect the logs:
journalctl --user -o cat | grep -E 'git-repo-watcher|ENOSPC|file watchers'
Observe that ChatGPT approaches the system limit and reports failures for paths inside .venv, caches, and Git-internal directories.
What is the expected behavior?
Codex should watch only the files needed to detect meaningful project changes.
It should ignore .venv, __pycache__, dependencies, caches, generated files, and most internal Git files.
Codex should reuse watchers when several tasks use the same repository. It should also release watchers when they are no longer needed.
Using several projects at the same time should not prevent other applications from working.
Additional information
I found several related reports, but none is an exact open report for my current Codex desktop problem.
Issue #33234 described almost the same Codex desktop behavior. Its author closed it one minute after creating it because they believed it was in the wrong repository. It was not closed because the bug was fixed.
Issue #23574 remains open and reports the same general watcher problem in the VS Code Codex extension. My report concerns the standalone ChatGPT desktop application while using Codex.
Issue #39123 is a recent Fedora report, but it concerns many helper processes holding empty watcher objects. My case concerns the main ChatGPT process watching approximately 65,000 actual files and folders.
My measurements were:
- Linux limit: 65,536 file watches
- Main ChatGPT process: 65,082 file watches
- First watcher group: 51,797 watched files
- Second watcher group: 13,279 watched folders
- Logs: 118 “Starting git repo watcher” messages in approximately 20 minutes
Watched paths included .venv, __pycache__, .git/objects, .git/modules, and .git/refs/codex/turn-diffs.
I collected and checked these measurements directly on my computer.
2 Comments
Confirming this on a different stack, and adding root-cause evidence from the shipped bundle plus a
node_modulescase that makes the scale worse than.venv.Environment: ChatGPT desktop
26.818.41705, Ubuntu 22.04.5 LTS, kernel 6.8.0-138-generic.Root cause in the shipped code. In
/usr/lib/chatgpt/resources/app.asar, thegit-repo-watcherclass (logger namegit-repo-watcher, telemetry opcodex.git.watcher_metadata) registers its working-tree watch target withrecursive: true. That watch target carries no ignore list at all — there is nonode_modules/.venvexclusion, no.gitignoreawareness, and no setting that scopes or disables it. On Linux the backend is inotify, so a recursive watch costs one watch per directory in the tree. For contrast, the neighbouringgit-init-watcherin the same bundle correctly usesrecursive: false.Scale on a JS monorepo. My workspace is a multi-repo Node.js tree:
So a single connected folder asks for ~1.6x the entire per-user allowance, and 87% of that is dependency directories that can never produce a meaningful git change. Failures in one day:
Sample paths it tried to watch:
Why this deserves priority over a normal watcher bug.
max_user_watchesis a per-user, system-wide resource. Once the desktop app drains it, every other process on the machine silently loses file watching — editors, dev servers, bundlers, test runners. The app degrades tools it has nothing to do with, and the failure surfaces in those tools, so users do not attribute it to Codex.Suggested fix, cheapest first: the working-tree watcher only needs to know that the tree changed, so honouring
.gitignore(or even a hardcoded skip ofnode_modules,.venv,__pycache__,.git/objects) at the recursive-watch level would remove the overwhelming majority of watches. A user-facing opt-out would be a reasonable stopgap while that lands.Neither documented workaround is acceptable as a default: not connecting large repos defeats the product, and raising
max_user_watchesasks every Linux user to re-tune a kernel limit because one app has no exclusion list.Confirming this on another supported Ubuntu system, including direct
/procmapping and an independent check of the latest shipped bundle.Environment
26.820.60940Direct inotify evidence
At one verified high-water snapshot:
fs.inotify.max_user_watches = 65,536The same main PID released and recreated large watch groups during sampling; observed counts included
29,824 -> 4,909 -> 26,675 -> 4,909 -> 15,437 -> 62,202. This is not merely one stable legitimate watch set.I mapped the two dominant instances through their
/proc/<pid>/fdinfoinode/device records:.venvnode_modulesRepository names, usernames, and absolute paths are intentionally omitted.
Independent latest-build implementation check
In the current
/usr/lib/chatgpt/resources/app.asar, I independently confirmed thatgit-repo-watcheradds the repository root as aworking-treedirectory target withrecursive: true. The file-watch request contains no registration-time ignore list. Failed watch sessions are scheduled for retry after 1,000 ms. The Git-internal-path predicate is used when handling delivered events, not to prevent recursive watches from being allocated.A separate 30-second observation found main-process RSS cycling between roughly 646 MiB and 1.39 GiB while the PID remained unchanged. I am not claiming that short sample alone proves a monotonic memory leak, but it is consistent with the repeated watcher construction and teardown.
This evidence supports an application defect triggered by large but ordinary project layouts, rather than an inotify or disk configuration problem. The key fixes appear to be registration-time exclusions, repository-level watcher deduplication, and bounded/backed-off recovery after quota exhaustion.