Error: ENOSPC inotify watch limit — что делать
Запускаешь dev-сервер большого проекта, и через секунду в консоли:
Error: ENOSPC: System limit for number of file watchers reached, watch '/path/to/project'Скажу честно: к самой ENOSPC (no space) это отношения не имеет. Места на диске у тебя полно. Просто Linux считает inotify watcher'ы — лимитированный системный ресурс — и ENOSPC выдаёт, когда он закончился. Сообщение мне всегда казалось обманчивым.
Проблема обычно встречается на больших монорепах, у Vite/Next/Webpack-проектов с тысячами файлов в node_modules. На macOS и Windows другие механизмы файловых вотчеров, поэтому ошибка только на Linux (и WSL).
Что такое inotify и почему он кончается
Inotify — это механизм Linux, который сообщает программам об изменениях в файловой системе. Каждый «слежкаемый» файл или директория — это watch. У ядра есть три параметра:
fs.inotify.max_user_watches— сколько вотчей может держать один пользователь;fs.inotify.max_user_instances— сколько экземпляров inotify;fs.inotify.max_queued_events— глубина очереди.
Дефолты на разных дистрибутивах разные, но часто это 8192 или 65536. Если у тебя в проекте больше файлов, чем лимит, dev-сервер тянет на каждый по watch и упирается.
Самая быстрая починка
Текущий лимит:
cat /proc/sys/fs/inotify/max_user_watchesПоднять без перезагрузки:
sudo sysctl fs.inotify.max_user_watches=524288Чтобы значение пережило ребут, добавляешь его в sysctl-конфиг:
echo 'fs.inotify.max_user_watches=524288' | sudo tee /etc/sysctl.d/99-inotify.conf
sudo sysctl -p /etc/sysctl.d/99-inotify.conf524288 — стандартное значение, которое советует большинство FAQ и которое выдержит даже большую монорепу. Можно ставить и меньше, если памяти у машины немного: каждый watcher — это около 1 КБ kernel memory. На 524288 это полгигабайта в худшем случае.
А почему сразу так много
Vite, Next в dev-режиме, Nodemon — все они вешают вотчи на исходники, на конфиги, на node_modules (в случае Vite — выборочно). Дополнительно у тебя в редакторе работает file watcher, индексер у IDE, иногда антивирус или утилита синхронизации. Каждая из этих программ ест из общего пула.
На свежем ноутбуке с одним проектом 8192 хватает. На рабочей машине с 5 параллельными монорепами и WebStorm в фоне — улетает мгновенно.
Кто ест больше всего
Если интересно, кто конкретно держит вотчеры, есть скрипт, который пробежится по всем процессам:
find /proc/*/fd -lname anon_inode:inotify 2>/dev/null \
| sed 's|/proc/\([0-9]*\)/fd/.*|\1|' | sort -u \
| xargs -r ps -pСписок процессов, которые держат хотя бы один inotify-instance. Дальше можно для каждого процесса посчитать число вотчей через /proc/$pid/fdinfo/ — но обычно достаточно понять, кто съедает (часто это твой IDE или Webpack).
Альтернативное решение: polling
Если не хочется (или нельзя) править системные параметры — можно переключить файловые вотчеры на режим polling. В этом случае инструмент сам опрашивает файлы по таймеру, не используя inotify. Нагрузка на CPU и батарею выше, зато ENOSPC исчезает.
В vite.config.js:
export default {
server: {
watch: {
usePolling: true,
interval: 300,
},
},
};В nodemon.json:
{
"legacyWatch": true
}В webpack:
module.exports = {
watchOptions: {
poll: 1000,
},
};На Docker-контейнерах с пробросом тома polling часто и так нужен — inotify туда не передаётся между хостом и контейнером.
Особый случай: WSL2
На WSL2 у пользователя свои значения fs.inotify.*, прописываются точно так же через /etc/sysctl.d/. Но! Если редактируешь файлы в Windows и они подмонтированы в WSL через /mnt/c/, события об изменениях из inotify не приходят вообще. Это ограничение DrvFS, и его не лечит ни один лимит. Нужно либо хранить проект внутри WSL-файловой системы (~/projects/..., не /mnt/c/...), либо включать polling.
Если поднял лимит — сразу проверь
cat /proc/sys/fs/inotify/max_user_watches
sysctl fs.inotify.max_user_instancesИногда люди забывают про max_user_instances, поднимают только max_user_watches, а ENOSPC возвращается через неделю. Подними и его в разумных пределах:
echo 'fs.inotify.max_user_instances=512' | sudo tee -a /etc/sysctl.d/99-inotify.conf
sudo sysctl -p /etc/sysctl.d/99-inotify.confЧто делаю на каждой новой Linux-машине
Я уже несколько лет первым делом, когда раскатываю Linux под разработку, пишу в /etc/sysctl.d/99-inotify.conf:
fs.inotify.max_user_watches=524288
fs.inotify.max_user_instances=512Применяю — и больше не возвращаюсь. На рабочих серверах эти лимиты обычно не нужны (там не запускается dev-сервер), а на машине разработчика это обязательная часть начальной настройки наравне с git и nvm.
Чек-лист
- Понять, действительно ли это лимит inotify (а не реальная нехватка места — на всякий случай
df -h). - Поднять
fs.inotify.max_user_watchesдо 524288. - Поднять
fs.inotify.max_user_instancesдо 256–512. - В Docker и WSL — рассмотреть polling.
- Закрепить через файл в
/etc/sysctl.d/.
Это разовое действие на пять минут, после которого dev-сервер перестаёт капризничать на больших проектах. Сообщение «ENOSPC» вводит в заблуждение, но решение всегда одно и то же.