Cursor’s fileWatcher process recursively watches a large workspace and can consume ~50k+ inotify watches (nearly the entire Linux default budget). After closing the workspace (Cursor app still running), the watcher process stays alive and keeps the watches. This is a resource leak.
Raising fs.inotify.max_user_watches is not an acceptable primary fix — it just hides Cursor’s leak and wastes kernel memory.
Steps to Reproduce
Steps to reproduce
On Linux, note current inotify usage (watches near zero / low hundreds is normal).
Open a large folder workspace in Cursor (monorepo with tens of thousands of directories), e.g. a big source tree.
Observe one utility process titled like:
fileWatcher [1:<workspaceStorageId>]
environ contains: VSCODE_ESM_ENTRYPOINT=vs/platform/files/node/watcher/watcherMain
Inotify watches jump to ~50k+.
Close the workspace / folder window, but do not quit Cursor (empty window is fine).
Check again: the fileWatcher process is still alive and still holds ~50k+ watches.
Only fully quitting Cursor, or manually killing that PID, releases the watches.
Control experiment (important)
Same machine, same large folder, VS Code 1.127.0:
Open the folder → watches rise.
Close the workspace, keep VS Code running.
Watches drop immediately. No leak.
So this appears Cursor-specific, not upstream VS Code.
Actual behavior
Workspace close does not dispose fileWatcher.
~50k+ inotify watches remain held.
Exhausts default Linux inotify budget; other apps then hit ENOSPC / “No space left on device” on inotify.
Expected Behavior
Closing a workspace must dispose its fileWatcher and drop all watches immediately.
Provide a hard opt-out to disable native file watching entirely, e.g. files.watcherEnable: false / “never watch”.
Do not tell Linux users to inflate fs.inotify.max_user_watches as the main fix.
files.watcherExclude is not enough here — dispose path is broken, and default recursive watch of huge trees is too aggressive.
Compared with: VS Code 1.127.0 on the same machine
Summary
Cursor’s fileWatcher process recursively watches a large workspace and can consume ~50k+ inotify watches (nearly the entire Linux default budget). After closing the workspace (Cursor app still running), the watcher process stays alive and keeps the watches. This is a resource leak.
Raising fs.inotify.max_user_watches is not an acceptable primary fix — it just hides Cursor’s leak and wastes kernel memory.
Steps to reproduce
On Linux, note current inotify usage (watches near zero / low hundreds is normal).
Open a large folder workspace in Cursor (monorepo with tens of thousands of directories), e.g. a big source tree.
Observe one utility process titled like:
fileWatcher [1:<workspaceStorageId>]
environ contains: VSCODE_ESM_ENTRYPOINT=vs/platform/files/node/watcher/watcherMain
Inotify watches jump to ~50k+.
Close the workspace / folder window, but do not quit Cursor (empty window is fine).
Check again: the fileWatcher process is still alive and still holds ~50k+ watches.
Only fully quitting Cursor, or manually killing that PID, releases the watches.
Control experiment (important)
Same machine, same large folder, VS Code 1.127.0:
Open the folder → watches rise.
Close the workspace, keep VS Code running.
Watches drop immediately. No leak.
So this appears Cursor-specific, not upstream VS Code.
Actual behavior
Workspace close does not dispose fileWatcher.
~50k+ inotify watches remain held.
Exhausts default Linux inotify budget; other apps then hit ENOSPC / “No space left on device” on inotify.
Expected behavior
Closing a workspace must dispose its fileWatcher and drop all watches immediately.
Provide a hard opt-out to disable native file watching entirely, e.g. files.watcherEnable: false / “never watch”.
Do not tell Linux users to inflate fs.inotify.max_user_watches as the main fix.
files.watcherExclude is not enough here — dispose path is broken, and default recursive watch of huge trees is too aggressive.
How to identify the leaked process
# find fileWatcher PIDs
for p in /proc/[0-9]*; do
grep -aq watcherMain "$p/environ" 2>/dev/null && {
echo "pid=${p##*/}"
tr '\0' '\n' < "$p/environ" | grep VSCODE_PROCESS_TITLE
}
done
I tried to reproduce this on Linux with a large folder (tens of thousands of directories) and, on my end, closing the folder disposes the fileWatcher and releases all its inotify watches within a few seconds. So I haven’t been able to confirm a leak yet, and I’d like to pin down what’s different in your setup.
One thing that’s easy to misread: when you close the folder, the window reloads into an empty window, and that empty window starts a new fileWatcher process. It only holds a handful of watches, but if you’re checking “is a fileWatcher still running?” you’ll see one - it just isn’t the old one. The thing to check is the watch count held by that PID, not whether a process exists.
Could you confirm a few things so I can dig in?
The exact close action - File → Close Folder (or “Close Workspace”), closing the window with the X, or something else? And is this a single-folder or multi-root workspace?
Right after closing, the watch count held by the surviving fileWatcher PID (your script is perfect for this - the number next to the PID, not just that it appears).
Whether it still happens on the latest stable build (your version is from late May).
Separately, for the underlying inotify pressure itself: the practical lever today is files.watcherExclude for the heavy directories, then reload the window. That reliably takes the count from ~65k down to a few hundred:
Then run Developer: Reload Window. Reducing how broadly we watch large trees by default on Linux is something we’re already looking at. There isn’t a global “never watch” toggle today, but I’ve noted that request. If you can grab the post-close watch count above, I’ll take it from there.
i notice the key path
first i open the agent window
it not run many watches
but when i open blank edit window
it can run 40k+ watches,sometimes it will hold 65k+ watches
after i close the edit window,
it not release the watches
after i close agent window, it will release the watches
in my opinion, when i close the edir window, cursor should release watches, rather than i close agent window
Here’s what’s going on. On the Agents Window, an edit window isn’t its own separate OS window; several of them live inside the one Agents Window. When you close just the edit window (File → Close Folder, or the editor view), that workspace’s file watcher isn’t disposed, so its inotify watches stay held. They’re only released when the whole Agents Window closes - which is exactly the difference you found between closing the edit window vs. the agent window. So this is a real dispose gap on the Agents Window on Linux, and I’ve reported it to our team.
That also fits your control test: regular VS Code opens one workspace per window, so closing a folder there disposes its watcher right away - it doesn’t have this multi-window-in-one model.
In the meantime, a few things:
To actually free the watches today, close the Agents Window (or fully quit Cursor), rather than only closing the edit window.
Keep your files.watcherExclude entries — that’s the right lever for how many watches each workspace holds (it’s why you went from ~50k to ~16k). Adding your repo’s other heavy generated/vendor directories will bring it down further.
If other tools hit ENOSPC in the meantime, raising fs.inotify.max_user_watches works as a temporary buffer only — I agree it’s a stopgap, not the fix.
On Wayland/Xwayland: that isn’t a factor here. inotify is handled in the kernel regardless of the display server, so the watch behavior is the same either way.
On a hard “never watch” switch: there isn’t a global toggle today (only the exclude/include lists), but I’ve noted the request.
No need to move to the latest build to help - you’ve already given us what we needed. I’ll update this thread when the fix lands.
ok,thank you
this is a heavy bug, in X11 env, when inotify runs out, some applications will not work
expect your good news about this problem
when it works i will try the new version