Linux: extensionHost + fileWatcher exhaust inotify limit (~65k); blocks Vite/dev tools (ENOSPC)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

On Linux (remote cursor-server), Cursor’s extensionHost and fileWatcher processes consume essentially the entire system inotify watcher budget (~65,532 / 65,536) during normal use with a multi-root workspace. No dev servers need to be running.

When the limit is hit, external tools fail immediately — e.g. Vite (npm run dev) errors with:

ENOSPC: System limit for number of file watchers reached, watch ‘…/.gitignore’

Closing terminals or stopping dev servers does not release watchers. Only Developer: Reload Window (or quitting Cursor) resets the count.

Measured via /proc/*/fdinfo before workaround:

  • extensionHost (node): ~49,820 watches
  • fileWatcher (node): ~15,202 watches
  • Total: ~65,532 (no Vite/node dev process running)

After adding files.watcherExclude (node_modules, target, dist, etc.) and reloading the window, total watches dropped to ~193 on the same workspace. That suggests Cursor watches too broadly by default and/or does not release watchers across long sessions.

Steps to Reproduce

  1. Linux machine with default inotify limit (fs.inotify.max_user_watches = 65536)
  2. Open Cursor with a multi-root workspace (4 folders: backend, frontend, docs, tooling repos)
  3. Use Cursor normally over a session (editing, agent chats, etc.) — only one dev environment at a time; close it when done
  4. Without raising sysctl limits, run npm run dev (Vite) in one project
  5. Vite fails immediately with ENOSPC before binding to port

To verify watcher ownership (no sensitive paths):
python3 -c "
import glob
total=0
for f in glob.glob(‘/proc/[0-9]/fdinfo/’):
try:
t=open(f).read()
if ‘inotify’ in t:
n=t.count(‘inotify wd:’)
if n: total+=n; print(n, f.split(‘/’)[2], open(‘/proc/’+f.split(‘/’)[2]+‘/comm’).read().strip())
except: pass
print(‘total’, total)
"
Expect extensionHost + fileWatcher to sum to ~65k while dev tools cannot start.

Expected Behavior

Cursor should not consume ~100% of the Linux inotify watcher budget under normal IDE usage. Heavy paths (node_modules, target/, dist/, .git/objects, build caches) should be excluded from watching by default (as VS Code typically does). Watchers should be released when no longer needed. External dev tools (Vite, etc.) should be able to run while Cursor is open.

Operating System

Linux

Version Information

IDE:
Version: 3.7.12
VSCode Version: 1.105.1
Commit: b887a26c4f70bd8136bfffeda812b24194ec9ce0

OS: Ubuntu 22.04, kernel 6.8.0-124-generic (x86_64)
Setup: Remote SSH / cursor-server on Linux

Additional Information

Workaround that fixes it for us (but shouldn’t be required):

  • files.watcherExclude for node_modules, target, dist, build, .git/objects, .cargo, graphify-out, backup folders
  • Developer: Reload Window after changing settings
  • Watch count: ~65,532 → ~193 after workaround + reload

We do not believe this is caused by running multiple dev servers. The ~65k watches were held by Cursor IDE processes alone with no Vite running.

Raising fs.inotify.max_user_watches unblocks dev tools but treats the symptom; Cursor should not need ~65k watchers for a 4-root workspace.

Does this stop you from using Cursor

Yes - Cursor is unusable

Hi Harry!

This is a known issue we’ve seen, and your read is correct: on Linux, Cursor watches each workspace folder recursively, and the default watch-exclude list only covers a few .git/.hg paths. It doesn’t exclude node_modules, target, dist, and similar heavy directories, so a multi-root workspace can use up most of the inotify budget and external tools like Vite then fail with ENOSPC. Our team is actively working on smarter default watch behavior here.

Your workaround is exactly the right lever, and worth keeping in place for now. For anyone landing here, the fix is to add the heavy directories to files.watcherExclude in settings and reload the window:

"files.watcherExclude": {
"**/node_modules/**": true,
"**/target/**": true,
"**/dist/**": true,
"**/build/**": true,
"**/.git/objects/**": true,
"**/.cargo/**": true
}

Then run Developer: Reload Window. As you saw, that takes the watch count from ~65k back down to a couple hundred. Raising fs.inotify.max_user_watches is a reasonable complementary OS-level safety net, but as you noted it treats the symptom - the exclude list is what actually keeps Cursor’s footprint small.

I’ll make sure your measurements get attached to the tracking work on this, since they’re a clean illustration of the default-watch footprint. Appreciate the thorough report.