Sửa lỗi Node.js ENOSPC: System limit for number of file watchers reached

beginner💚 Node.js2026-03-17| Linux (Ubuntu, Debian, CentOS, Fedora), Node.js 14+, các công cụ: webpack, Vite, Create React App, Next.js, nodemon, VSCode

Error Message

Error: ENOSPC: System limit for number of file watchers reached
#nodejs#inotify#watchers

Tình huống gặp lỗi

Chạy npm start hoặc npm run dev rồi bị crash với thông báo:

Error: ENOSPC: System limit for number of file watchers reached, watch '/path/to/project'
    at FSWatcher. (/project/node_modules/chokidar/lib/fsevents-handler.js:180:19)

Linux có giới hạn ở cấp kernel về số lượng file và thư mục có thể theo dõi đồng thời thông qua inotify. Khi kết hợp node_modules (có thể chứa hơn 50.000 file trong một dự án hiện đại), cây thư mục nguồn, và các tiến trình khác như VSCode hay Dropbox — bạn đã vượt quá giới hạn đó.

Các nguyên nhân thường gặp: khởi động webpack dev server, chạy nodemon, mở một monorepo lớn trong VSCode, hoặc khởi chạy nhiều dev server cùng lúc.

Debug: xác nhận đây là lỗi giới hạn inotify

Kiểm tra giới hạn hiện tại và mức sử dụng:

# Số watcher tối đa hiện tại
cat /proc/sys/fs/inotify/max_user_watches

# Số instance được phép
cat /proc/sys/fs/inotify/max_user_instances

# Xem tiến trình nào đang tiêu tốn watch
find /proc/*/fd -lname anon_inode:inotify 2>/dev/null | \
  awk -F/ '{print $3}' | xargs -I{} sh -c 'echo -n "{}: "; cat /proc/{}/cmdline | tr "\0" " "; echo'

Một cài đặt Linux mặc định chỉ đặt max_user_watches8192. Đó chính là nguyên nhân. Một dự án Next.js hoặc CRA cỡ trung bình có thể ngốn từ 8.000 đến 15.000 watcher — riêng node_modules đã chiếm phần lớn con số đó.

Sửa tạm thời (mất sau khi khởi động lại)

sudo sysctl fs.inotify.max_user_watches=524288

Khởi động lại dev server ngay sau đó. Nếu server chạy bình thường, cách sửa này có tác dụng — nhưng sẽ mất sau khi reboot. Hãy làm cho nó vĩnh viễn ở bước tiếp theo.

Sửa vĩnh viễn

Ghi giá trị vào sysctl.conf:

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Trên Ubuntu 20.04+ và Debian, cách gọn hơn là tạo một file config riêng:

echo 'fs.inotify.max_user_watches=524288' | sudo tee /etc/sysctl.d/99-inotify-watches.conf
sudo sysctl --system

Cả hai cách đều hoạt động. Giá trị 524288 (~512K) là chuẩn cộng đồng — tài liệu webpack, các issue của Next.js, và nhiều năm câu trả lời trên Stack Overflow đều đồng thuận ở con số này. Đang dùng monorepo hoặc mở nhiều dự án cùng lúc? Hãy nhân đôi lên:

# Dành cho monorepo hoặc nhiều dự án mở cùng lúc
echo 'fs.inotify.max_user_watches=1048576' | sudo tee /etc/sysctl.d/99-inotify-watches.conf
sudo sysctl --system

Kiểm tra sau khi sửa

# Xác nhận giá trị mới đã được áp dụng
cat /proc/sys/fs/inotify/max_user_watches
# Kết quả phải là: 524288

Khởi động lại dev server. Server sẽ chạy bình thường. Đang dùng WSL2? Còn một bước nữa.

Lưu ý cho WSL2

WSL2 không áp dụng thay đổi từ sysctl.conf khi khởi động theo cách giống Linux thông thường. Có hai lựa chọn:

Thêm lệnh khởi động vào /etc/wsl.conf (khuyến nghị):

[boot]
command = sysctl -w fs.inotify.max_user_watches=524288

Hoặc đặt trong shell profile như một phương án dự phòng:

# Trong ~/.bashrc hoặc ~/.zshrc của bạn
if [ -f /proc/sys/fs/inotify/max_user_watches ]; then
  sudo sysctl -w fs.inotify.max_user_watches=524288 > /dev/null 2>&1
fi

Cách dùng wsl.conf gọn hơn — hãy dùng cách đó.

Mẹo thêm: giảm số watcher thay vì tăng giới hạn

Không có quyền root? Trên server dùng chung hoặc container có quyền hạn chế, hãy thu gọn những gì cần theo dõi:

  • Thêm node_modules vào danh sách ignore trong .watchmanconfig nếu đang dùng Watchman
  • Trong webpack, đặt watchOptions.ignored: /node_modules/
  • Trong Vite, cấu hình server.watch.ignored
  • Trong VSCode, thêm node_modules và các thư mục build vào files.watcherExclude trong settings
// vite.config.ts
export default defineConfig({
  server: {
    watch: {
      ignored: ['**/node_modules/**', '**/dist/**']
    }
  }
})
// webpack.config.js
module.exports = {
  watchOptions: {
    ignored: /node_modules/,
  }
}

Bài học rút ra

  • Giới hạn mặc định 8192 có từ trước thời npm — hãy tăng nó trên mọi máy dev Linux ngay khi cài đặt, trước khi gặp lỗi này
  • Các dự án lớn cộng dồn rất nhanh: editor + dev server + test watcher có thể mỗi thứ tiêu tốn hàng nghìn watch cùng lúc
  • Riêng VSCode đã ngốn hàng nghìn watcher trên một repo lớn — kiểm tra files.watcherExclude trong settings nếu bạn liên tục gặp lỗi này
  • Các Docker container kế thừa giới hạn inotify từ host — hãy sửa trên host, không phải bên trong container
  • Mỗi watcher tốn khoảng 1KB bộ nhớ kernel; tăng lên 524288 dùng tối đa ~512MB, nhưng trên thực tế ít hơn nhiều

Related Error Notes