v5.0
live available
devtools guide 14 Oct 2026

Four file watchers, one repo, and the 65,536 the kernel will lend you

Two of the four took a watch per file instead of per directory, which is 78 percent of the whole budget for one watcher on one repo. Start a second and it dies.

By Purvansh Parmar Checked 2026-10-21 Read 7 min Entries 4

Your dev server stops reloading. Nothing in its output says why, the disk has 235 GB free, and restarting it fixes the problem until the next time. The cause is a counter you have probably never read: a single per user limit on how many files the kernel will let you watch, shared by your editor, your dev server, your test runner and anything else holding an inotify handle. On this machine it is 65,536. One watcher on one repo took 51,105 of them.

How this was checkedPointed four recursive file watchers at the same 5,006 directory repo and measured the delta in this user's total inotify watch count across every process. Two of them took roughly 51,100 watches against a ceiling of 65,536. Then started one watcher, waited for it to settle, and started a second: it died with ENOSPC. Also allocated watches until the kernel refused, inside a container running as a uid nothing else uses, which put the refusal at exactly 65,536 with errno 28.

What I compared on

01 @parcel/watcher

Native watcher used by Parcel and others, with a C++ backend per platform rather than a JavaScript loop.

Wins
It is the only Node watcher here that scales with directories instead of files, which means a repo with ten times the files costs it nothing extra. Twelve of these could run at once before teh kernel objected.
Loses
It is a native module, so it carries prebuilt binaries and a build fallback, and 72 MB of RSS is seven times the raw syscall baseline for the identical watch count.
5,006 watches72 MB RSS7.6 percent of the budget

02 inotify directly

The syscall underneath all of them, called through ctypes with one watch added per directory.

Wins
Nothing is cheaper. It also makes the accounting legible: one watch per directory, no library deciding on your behalf how much of a shared budget to spend.
Loses
You are now writing a file watcher. Event coalescing, rename tracking, the fact that a watch on a directory does not cover its subdirectories, and overflow handling when the queue exceeds 16,384 events are all yours to implement.
5,006 watches10 MB RSSrefused at 65,536

03 node fs.watch recursive

The built in watcher with recursive true, which Linux only gained support for in recent Node versions.

Wins
It is in the standard library, it is three lines, and it has no dependency. For a single small directory it is exactly the right tool and costs nothing to reach for.
Loses
Pointed at a repo with node_modules it quietly takes most of the machine's watch budget, and nothing in the API hints that recursive means per file. The second watcher on the box is then the one that fails.
51,105 watches163 MB RSS78 percent of the budget

04 chokidar 3.6.0

The watcher underneath a large share of the JavaScript tooling you already run, including many dev servers.

Wins
It is the most battle tested of the four and it normalises a genuinely nasty cross platform problem, which is why so much tooling depends on it rather than calling the syscall.
Loses
It spends the same per file budget as the built in watcher and 2.1 times the memory to do it. The failure, when it comes, is an unhandled error that takes the process down rather than a degraded mode.
51,104 watches338 MB RSSdies at the ceiling

Side by side

WatchesShare of 65,536RSS
inotify directly5,0067.6%10 MB
@parcel/watcher5,0067.6%72 MB
chokidar 3.6.051,10478.0%338 MB
node fs.watch -r51,10578.0%163 MB

Verdict

Use @parcel/watcher if you are choosing, and if you are not choosing, go and read /proc/sys/fs/inotify/max_user_watches before you believe your dev server is healthy. The gap is not subtle: 5,006 watches against 51,105 for the same tree, because one of them watches directories and the other watches files. The part that makes this an outage rather than a setting is that the budget is per user and the error is ENOSPC, so the first thing everyone does is check the disk, find 235 GB free, and go looking somewhere else entirely.

Sources