VPS ENOSPC: Fix "System Limit for File Watchers Reached"
Your Node app won't start, PM2 refuses to watch for file changes, or VS Code Server on your VPS throws a wall of red text — and buried in it is one line: ENOSPC: System limit for number of file watchers reached. Nothing's out of disk space, nothing's out of RAM. It's a different limit entirely, and it trips up almost everyone the first time they hit it.
Symptom
You'll usually see one of these, depending on what's running on the VPS:
Error: ENOSPC: System limit for number of file watchers reached, watch '/home/user/app/node_modules/...'from a Node.js process (webpack dev server, Next.js, Vite, nodemon)- PM2 in watch mode silently stops picking up file changes, or logs the same ENOSPC error and exits
- VS Code Server / code-server running on the VPS shows "Visual Studio Code is unable to watch for file changes in this large workspace"
- Git hooks or file-sync tools (like a CI runner or a Chokidar-based watcher) fail partway through startup with no other explanation
The confusing part: df -h shows plenty of disk space free, and free -m shows plenty of RAM. ENOSPC here doesn't mean "no space on disk" — it means the kernel has run out of a completely different resource: inotify watch slots.
Cause
Linux uses a kernel subsystem called inotify to let processes subscribe to filesystem change events — "tell me when this file gets modified." Every file a dev tool watches (and with node_modules, that can be tens of thousands of files) consumes one watch slot from a system-wide pool.
That pool has a hard ceiling, controlled by a kernel parameter: fs.inotify.max_user_watches. On a stock Ubuntu or CentOS/AlmaLinux VPS, the default is usually 8192 — sometimes as low as 128 on minimal cloud images. A single modern JavaScript project with a deep node_modules tree can blow past 8192 watches on its own, before you've even opened a second project or started code-server.
This is purely a VPS/Linux thing. It doesn't show up on shared cPanel hosting because you're not running long-lived watch processes there, and it doesn't show up on most developers' laptops because desktop Linux distros ship with a much higher default (commonly 524288 or more).
It also tends to show up at the worst possible time — not when you first deploy a project, but weeks later when a dependency update adds a few thousand extra files to node_modules, or when you spin up a second project on the same box and its watcher pushes the combined total over the ceiling. That's why it often reads as "this used to work and now it doesn't," even though nothing about your code changed.
Related but separate limits that sometimes stack on top of this:
fs.inotify.max_user_instances— how many separate inotify "sessions" one user can open (default often 128)fs.inotify.max_queued_events— how many pending events can queue up before the oldest get dropped (rarely the culprit, but worth knowing)
Fix
1. Check your current limits
SSH into the VPS and run:
cat /proc/sys/fs/inotify/max_user_watches
cat /proc/sys/fs/inotify/max_user_instances
If max_user_watches comes back at 8192 or lower, that's almost certainly your problem.
2. Raise the watch limit
Set it for the current session first, to confirm the fix works before making it permanent:
sudo sysctl fs.inotify.max_user_watches=524288
Restart the app or watcher and confirm the error is gone. Once you've verified it, make the change survive a reboot by writing it to a sysctl config file:
echo "fs.inotify.max_user_watches=524288" | sudo tee /etc/sysctl.d/99-inotify.conf
echo "fs.inotify.max_user_instances=512" | sudo tee -a /etc/sysctl.d/99-inotify.conf
sudo sysctl --system
524288 is a safe, commonly-used ceiling — it costs roughly 1KB of unswappable kernel memory per 1000 watches, so even a generous limit only uses a few hundred KB of RAM. There's no real downside to setting it high on a VPS you control.
3. If you're on a container platform (Docker, LXC)
If the watcher runs inside a Docker container, the inotify limit is a kernel-level setting that belongs to the host, not the container — you can't raise it from inside the container's namespace. Set it on the VPS host itself as above, and it applies to every container running on that host.
4. If you can't get root (managed VPS or restricted account)
Some managed VPS plans or CI environments don't grant sysctl access. In that case, reduce how many files get watched instead of raising the ceiling:
- Add
node_modules,.git, and build output folders (dist,.next,build) to your watcher's ignore list — for webpack/Vite/Next this is usually awatchOptions.ignoredorserver.watch.ignoredconfig entry - In PM2, disable watch mode for dependencies:
pm2 start app.js --watch --ignore-watch="node_modules .git logs" - In VS Code / code-server, add heavy folders to
files.watcherExcludein settings
Prevention
A few habits keep this from coming back once you've fixed it:
- If you provision VPS servers with a script (Ansible, cloud-init, a setup shell script), bake the
/etc/sysctl.d/99-inotify.conffile into it so every new server starts with a sane limit — don't rely on remembering to fix it manually each time. - Keep watcher ignore lists in your project config (not just your personal editor settings) so every developer and every CI runner benefits, not just the machine where you first hit the error.
- If a single VPS is running several active dev/staging projects with live-reload watchers plus code-server plus PM2 watch mode simultaneously, you're stacking watch consumers — consider whether some of them (like PM2 watch mode in a staging environment) actually need to run at all.
Quick reference
| Kernel parameter | What it controls | Safe VPS value |
|---|---|---|
fs.inotify.max_user_watches | Total files one user can watch across all processes | 524288 |
fs.inotify.max_user_instances | Number of separate watcher "sessions" one user can open | 512 |
fs.inotify.max_queued_events | Pending events queued per instance before old ones drop | 16384 (default is usually fine) |
Frequently asked questions
Why does this only happen on my VPS and not my laptop?
Desktop Linux distros (Ubuntu Desktop, Fedora, etc.) ship with a much higher default fs.inotify.max_user_watches, often 524288 or more. Minimal server images used for VPS deployments default much lower -- commonly 8192 -- because most server workloads never watch files at all.
Will raising fs.inotify.max_user_watches use a lot of memory or hurt performance?
No. Each watch costs roughly 1KB of unswappable kernel memory, so even 524288 watches only reserves a few hundred KB. There's no measurable performance cost from raising the limit on a VPS you control.
I raised the limit but the error still happens inside my Docker container. Why?
inotify limits belong to the host kernel, not the container namespace. You have to set fs.inotify.max_user_watches on the VPS host itself -- sysctl commands run inside a container won't persist or apply system-wide.
Does this affect cPanel shared hosting too?
Rarely. Shared cPanel hosting doesn't normally run long-lived file watchers like webpack dev servers, PM2 watch mode, or code-server, so the default inotify limits are almost never hit there. This is mainly a VPS/VM issue.
How do I know if inotify watches are actually the bottleneck and not something else?
Run cat /proc/sys/fs/inotify/max_user_watches. If it returns 8192 or lower and the error message explicitly says ENOSPC: System limit for number of file watchers reached, you've confirmed it -- that exact wording only comes from hitting this specific kernel limit.