How to fix Error: EMFILE: too many open files, watch in Node.js

Node.jsINTERMEDIATEHIGHUpdated Dec 22, 2025ยท 244 views

This error occurs when fs.watch() exceeds the operating system limit for file watchers. File system watchers consume limited system resources, and watching too many files simultaneously exhausts these limits.

Quick fix

Fixes EMFILE

# Check the inotify watch limit
cat /proc/sys/fs/inotify/max_user_watches

# Typical output: 8192
  1. Check your system inotify limit on Linux
  2. Temporarily increase inotify limit for testing
  3. Permanently increase inotify limit on Linux
  4. Exclude unnecessary directories from watching
node.js โ€” error
# Check the inotify watch limit
cat /proc/sys/fs/inotify/max_user_watches
# Typical output: 8192
Error: EMFILE: too many open files, watch

What this error means

The fs.watch() limit exceeded error is a system-level resource constraint that occurs when your Node.js application attempts to watch more files than the operating system permits. Unlike general file descriptor limits, file system watchers use a separate system resource pool that is often more limited. On Linux systems, inotify is used for file watching, with a default limit of 8192 watches per user. On macOS, FSEvents has different limitations, and on Windows, directory change notifications have their own constraints. When you exceed these limits, fs.watch() fails with an EMFILE error. This is particularly common in development tools, build systems, and file monitoring applications that watch entire project directories recursively. Each file or directory being watched consumes one watch handle from the system pool.

Typical symptoms

  • fs.watch() fails with "Error: EMFILE: too many open files, watch"
  • File watcher stops working after watching multiple directories
  • Build tools or development servers fail to start when projects have many files
  • Error occurs specifically when using fs.watch() or fs.watchFile() on large codebases
  • Problem appears only on Linux systems, not on macOS or Windows
  • IDE or editor file watcher crashes when opening large projects

Common causes

  1. Watching too many files or directories recursively without filtering
  2. System inotify limit on Linux is too low for the number of watched files
  3. Watching entire project directories including node_modules without exclusions
  4. Multiple watch instances competing for the same system resource limit
  5. Not properly closing watch instances when they are no longer needed
  6. Watching generated files or cache directories that contain thousands of files

How to fix "Error: EMFILE: too many open files, watch"

1Check your system inotify limit on Linux

First, verify the current file watch limit on your system:

bash
# Check the inotify watch limit
cat /proc/sys/fs/inotify/max_user_watches

# Typical output: 8192

If the number is 8192 or lower and you're watching many files, this is likely your issue. The default limit is often insufficient for large projects.

2Temporarily increase inotify limit for testing

To quickly test if increasing the limit fixes the problem:

bash
# Increase to 65536
sudo sysctl -w fs.inotify.max_user_watches=65536

# Then run your Node.js application
node your-app.js

This change applies immediately but will reset when you reboot. Use this to confirm the fix before making it permanent.

3Permanently increase inotify limit on Linux

To make the change permanent across reboots, edit /etc/sysctl.conf:

bash
sudo nano /etc/sysctl.conf

Add this line at the end:

bash
fs.inotify.max_user_watches=65536

Save and apply the changes:

bash
sudo sysctl -p

Verify the new limit:

bash
cat /proc/sys/fs/inotify/max_user_watches
4Exclude unnecessary directories from watching

The most practical solution is to watch fewer files by excluding large directories:

javascript
const fs = require('fs');
const path = require('path');

function watchDir(dir, callback, excludeDirs = []) {
  const files = fs.readdirSync(dir);
  
  files.forEach(file => {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);
    
    // Skip excluded directories
    if (stat.isDirectory() && excludeDirs.includes(file)) {
      return;
    }
    
    if (stat.isDirectory()) {
      watchDir(filePath, callback, excludeDirs);
    } else {
      fs.watch(filePath, callback);
    }
  });
}

// Watch src directory but exclude node_modules, dist, .git
watchDir('./src', (eventType, filename) => {
  console.log('File changed:', filename);
}, ['node_modules', 'dist', '.git', '.next', 'build']);
5Use chokidar for efficient file watching

chokidar is more efficient than fs.watch and provides better control:

bash
npm install chokidar
javascript
const chokidar = require('chokidar');

// Watch only necessary files
const watcher = chokidar.watch(['src/**/*.js', 'src/**/*.ts'], {
  ignored: ['**/node_modules', '**/.git', '**/dist'],
  usePolling: false,
  awaitWriteFinish: {
    stabilityThreshold: 100,
    pollInterval: 100
  }
});

watcher
  .on('change', (path) => console.log('File changed:', path))
  .on('add', (path) => console.log('File added:', path))
  .on('unlink', (path) => console.log('File removed:', path))
  .on('error', (error) => console.error('Watcher error:', error));

// Properly close watchers
process.on('SIGINT', () => {
  watcher.close();
  process.exit(0);
});
6Use glob patterns to watch specific files

Instead of watching directories recursively, watch only the files you care about:

javascript
const glob = require('glob');
const fs = require('fs');

// Find all source files matching pattern
glob('src/**/*.{js,ts,jsx,tsx}', (err, files) => {
  if (err) throw err;
  
  files.forEach(file => {
    fs.watch(file, (eventType, filename) => {
      console.log('Changed:', filename);
    });
  });
});

This watches only source files and ignores build output, dependencies, and other unnecessary files.

7Properly close watch instances

Always close watch instances when done to free up resources:

javascript
const fs = require('fs');

const watcher = fs.watch('file.txt', (eventType, filename) => {
  console.log('File changed:', filename);
});

// Later, close the watcher
watcher.close();

// Or for multiple watchers, close all
const watchers = [];

function closeAllWatchers() {
  watchers.forEach(w => w.close());
  watchers.length = 0;
}

process.on('SIGINT', () => {
  closeAllWatchers();
  process.exit(0);
});
8Use Node.js built-in stable API when possible

If your use case allows, use more efficient approaches than file watching:

javascript
// Instead of watching for changes, use polling with debouncing
const debounce = require('lodash.debounce');
const fs = require('fs').promises;

const checkFile = debounce(async () => {
  const stats = await fs.stat('config.json');
  console.log('Config modified:', stats.mtime);
}, 500);

fs.watch('config.json', () => checkFile());

// Or use fs.watchFile for single files
fs.watchFile('config.json', (current, previous) => {
  if (current.mtime !== previous.mtime) {
    console.log('Config changed');
  }
});

Advanced notes

Platform-Specific Limits: On Linux, the inotify limit (/proc/sys/fs/inotify/max_user_watches) is the primary constraint. On macOS, FSEvents is unlimited for the OS but Node.js may have practical limits. Windows directory change notifications are less resource-constrained but have different behavior.

Docker Environments: When running Node.js in Docker containers, the inotify limit is inherited from the host system. Increase it on the host or use --sysctl fs.inotify.max_user_watches=65536 when running Docker containers.

Production Considerations: In production, avoid using fs.watch() altogether. Instead, use message queues, webhooks, or external monitoring. File watching is primarily a development tool.

Chokidar vs fs.watch: Chokidar is more reliable and efficient than native fs.watch() for most use cases. It handles edge cases better and provides progress reporting. Consider it the standard for professional development tools.

Memory Efficiency: Each watch instance consumes memory in addition to system watch limits. Watching thousands of files not only hits system limits but also consumes significant RAM. Filtering is essential.

IDE Integration: Development environments (VS Code, WebStorm, etc.) may have their own file watcher limits that interact with your Node.js application's limits. Check IDE settings if watching doesn't work as expected.

Frequently asked questions

What does "EMFILE" mean?
js application attempts to watch more files than the operating system permits. Unlike general file descriptor limits, file system watchers use a separate system resource pool that is often more limited. On Linux systems, inotify is used for file watching, with a default limit of 8192 watches per user.
How do I fix "EMFILE"?
This error occurs when fs.watch() exceeds the operating system limit for file watchers. File system watchers consume limited system resources, and watching too many files simultaneously exhausts these limits.
What causes "EMFILE"?
Watching too many files or directories recursively without filtering System inotify limit on Linux is too low for the number of watched files Watching entire project directories including node_modules without exclusions
Is the "EMFILE" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading