Выберите продукт

inotify ENOSPC в Linux: увеличиваем лимиты watches/instances для IDE, watch и CI

inotify ENOSPC часто появляется в VS Code, PhpStorm, webpack/vite watch и на CI runners: системе не хватает лимитов watches/instances или переполняется очередь событий. Разберём диагностику, практичные значения и настройку через sysctl.d и systemd-sysctl.
inotify ENOSPC в Linux: увеличиваем лимиты watches/instances для IDE, watch и CI

Что значит inotify ENOSPC и почему это не про место на диске

Когда IDE или сборщик пишет ENOSPC: System limit for number of file watchers reached, первая мысль — проверить свободное место. Но в контексте inotify код ENOSPC почти всегда означает «закончился системный ресурс» (лимит), а не «диск заполнен».

inotify — подсистема ядра Linux для уведомлений о событиях в файловой системе: изменение файла, создание, удаление и т.д. На неё опираются dev-серверы, IDE, сборщики и CI-агенты.

Проблема возникает, когда суммарное число наблюдений (watches) или экземпляров inotify (instances) превышает лимит, либо когда очередь событий переполняется (обработчик не успевает).

Три главных лимита: watches, instances и queued events

Практически все случаи ENOSPC упираются в один из трёх параметров sysctl:

  • fs.inotify.max_user_watches — сколько «точек наблюдения» (watch) может создать один пользователь (UID). Обычно watch ставится на директории (реже на отдельные файлы — зависит от инструмента).
  • fs.inotify.max_user_instances — сколько экземпляров inotify может создать один пользователь. Условно: сколько независимых «клиентов» inotify может жить параллельно.
  • fs.inotify.max_queued_events — максимальный размер очереди событий. При шторме событий и медленном обработчике возможны переполнения и пропуски.

Увеличение лимитов лечит симптом. Если инструмент наблюдает каталог, куда сам же пишет артефакты, вы получите шторм событий и нагрузку даже при больших значениях.

В продакшене и на сборочных агентам это особенно заметно: много проектов, много параллели, большие рабочие каталоги. Если вам нужна отдельная машина под CI/сборки, удобнее держать преднастроенный профиль sysctl на VDS, чтобы ловить меньше «внезапных» падений вотчеров.

Рабочее место разработчика: IDE предупреждает о file watchers, рядом открыт терминал Linux

Как выглядит ошибка на практике (VS Code, webpack, PhpStorm, CI)

Типичные сообщения, которые вы увидите в логах или UI:

  • Node.js/webpack/vite/nodemon: ENOSPC: System limit for number of file watchers reached.
  • VS Code: перестаёт обновляться дерево файлов, ломается auto-reload, появляются уведомления о проблемах с file watcher.
  • PhpStorm/WebStorm: File Watchers отваливаются, индексация работает нестабильно, появляются предупреждения о нехватке watchers.
  • CI runners: сборка падает только на конкретном агенте, где одновременно крутится много джобов и workspace большой.

Иногда рядом всплывает «too many open files». Это уже лимиты файловых дескрипторов (FD) и ulimit — отдельная, но часто сопутствующая история. Если нужно быстро закрыть оба класса проблем, посмотрите мой разбор про лимиты FD и inotify: как связаны nofile и inotify и где их настраивать.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Быстрая диагностика: текущие значения sysctl

Сначала зафиксируйте текущие лимиты:

sysctl fs.inotify.max_user_watches
sysctl fs.inotify.max_user_instances
sysctl fs.inotify.max_queued_events

Эквивалентно можно читать напрямую из /proc:

cat /proc/sys/fs/inotify/max_user_watches
cat /proc/sys/fs/inotify/max_user_instances
cat /proc/sys/fs/inotify/max_queued_events

Как понять, во что именно вы упираетесь

Если сообщение явно говорит про watchers — почти всегда достаточно поднять fs.inotify.max_user_watches. Если на машине много сервисов от одного пользователя (например, runner запускает всё под gitlab-runner) — можно упереться в fs.inotify.max_user_instances.

Если же у вас интенсивная генерация файлов (компиляция, синхронизация артефактов, автоформатирование), и при этом наблюдается «буря» событий, узким местом иногда становится fs.inotify.max_queued_events.

Временное решение до перезагрузки (проверить гипотезу)

Чтобы быстро подтвердить, что проблема именно в лимитах inotify, поднимите значения на лету. Это не переживёт перезагрузку:

sudo sysctl -w fs.inotify.max_user_watches=524288
sudo sysctl -w fs.inotify.max_user_instances=1024
sudo sysctl -w fs.inotify.max_queued_events=32768

Если после этого IDE/сборка/пайплайн ожили — фиксируем настройку правильно через sysctl.d.

Постоянная настройка через sysctl.d (правильный способ)

На современных дистрибутивах удобнее завести отдельный файл в /etc/sysctl.d/, чтобы не смешивать параметры и проще откатывать.

Создайте, например, /etc/sysctl.d/99-inotify.conf:

sudo sh -c 'cat > /etc/sysctl.d/99-inotify.conf <<EOF
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 1024
fs.inotify.max_queued_events = 32768
EOF'

Примените настройки:

sudo sysctl --system

Или примените только один файл:

sudo sysctl -p /etc/sysctl.d/99-inotify.conf

systemd-sysctl: порядок применения и «почему не применилось»

Если после перезагрузки значения снова «не те», скорее всего, есть переопределение из другого файла sysctl.d, либо настройки применяются в неожиданном порядке.

Проверьте состояние сервиса и итоговую «склейку» конфигов:

systemctl status systemd-sysctl
systemd-analyze cat-config sysctl.d

В выводе systemd-analyze cat-config sysctl.d видно, какие файлы влияют на итог и кто переопределил ваши значения.

Какие значения ставить: практические ориентиры

Универсального числа нет: влияет размер репозитория, количество параллельных процессов и то, наблюдаете ли вы тяжёлые каталоги (вроде node_modules), vendor-директории, артефакты сборки и кеши.

Ориентиры, которые чаще всего решают проблему на dev/CI без фанатизма:

  • fs.inotify.max_user_watches: 262144 или 524288 для больших проектов и монореп.
  • fs.inotify.max_user_instances: 512 или 1024, если много параллельных процессов (IDE + несколько watch + тесты).
  • fs.inotify.max_queued_events: 16384–32768, если есть признаки шторма событий.

На CI runners помните: один пользователь может обслуживать много джобов. Иногда эффективнее не только поднять лимиты, но и ограничить параллелизм исполнителей на одном агенте, чтобы не умножать watchers на N.

Логи CI runner с ошибкой inotify и сообщением о нехватке file watchers

Как найти «пожирателя» watchers

Частая ситуация: лимит «съедает» не тот процесс, на который вы думаете (например, не сборщик, а IDE или несколько забытых dev-серверов в фоне).

Приблизительно потребление inotify можно оценить по дескрипторам anon_inode:inotify. Пример для текущего процесса:

ls -l /proc/self/fd | grep -c inotify

Чтобы получить топ процессов по inotify (нужны права root):

sudo lsof -n | grep -F anon_inode:inotify | awk '{print $1, $2}' | sort | uniq -c | sort -nr | head

Дальше действуйте точечно: закрывайте лишние проекты/IDE, убирайте лишние watch-процессы, добавляйте исключения каталогов в конфиги сборки/инструментов.

Частые причины, почему лимитов не хватает

Большие деревья: node_modules, vendor, .git, build

Современные проекты легко создают десятки и сотни тысяч файлов. Если watcher рекурсивно подписывается на всё подряд, fs.inotify.max_user_watches заканчивается мгновенно.

Практика: исключайте тяжёлые каталоги из наблюдения и индексации. В сборщиках это обычно ignore/exclude, в IDE — «Excluded» для build output, кешей, зависимостей.

Watcher смотрит на директорию, куда сам же пишет

Классика: сборка пишет артефакты в папку внутри проекта, а watcher наблюдает весь проект целиком. Получается петля событий «изменение → сборка → артефакты → события», и тогда может упереться даже fs.inotify.max_queued_events.

CI runners: много параллели и «хвосты» процессов

На CI проблема часто проявляется «внезапно», потому что runners крутят несколько задач одновременно. Каждая задача поднимает собственные watchers, а иногда ещё и сервисы (dev server, тестовый раннер).

Если агенты живут долго, следите за «хвостами»: зависшие процессы продолжают держать watchers. Если вы строите пайплайны на inotify-триггерах, может быть полезен подход с systemd path units; см. также: systemd Path + inotify для CI и фоновых задач.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Связанный класс проблем: «too many open files» и лимиты nofile

ENOSPC в inotify и «too many open files» часто приходят парой: инструмент одновременно открывает много файлов и ставит много наблюдений. Поэтому повышение только fs.inotify.* может дать частичный эффект.

Быстрая проверка FD лимитов:

ulimit -n
cat /proc/$(pidof -s code)/limits | grep -i open

Если лимит мал, лечите оба слоя: sysctl для inotify и лимиты FD (ulimit/systemd LimitNOFILE).

Мини-рукбук для админа: что делать, если упало на CI/сборочном агенте

  1. Зафиксировать симптом: текст ошибки (watches/instances/queue), какой процесс и под каким пользователем.
  2. Проверить текущие значения: sysctl fs.inotify.max_user_watches fs.inotify.max_user_instances fs.inotify.max_queued_events.
  3. Временно поднять лимиты через sysctl -w и подтвердить, что пайплайн/вотчер ожили.
  4. Внести постоянную настройку в /etc/sysctl.d/99-inotify.conf, применить sudo sysctl --system.
  5. Если повторяется: найти топ процессов по anon_inode:inotify и привести в порядок ignore/exclude.
  6. Проверить лимиты FD (ulimit -n, systemd unit overrides), если рядом есть «too many open files».

Проверка результата и контроль изменений

После применения убедитесь, что значения реально изменились:

sysctl fs.inotify.max_user_watches fs.inotify.max_user_instances fs.inotify.max_queued_events

Если после перезагрузки снова старые значения — ищите переопределение:

systemd-analyze cat-config sysctl.d

И не забывайте про гигиену watch-настроек: исключения для зависимостей и артефактов часто дают больший эффект, чем бесконечное повышение лимитов.

Поделиться статьей

Вам будет интересно

Kubernetes на VDS: conntrack, nf_conntrack_max и всплески dport scan OpenAI Статья написана AI (GPT 5)

Kubernetes на VDS: conntrack, nf_conntrack_max и всплески dport scan

Если на Kubernetes-нодах появляются «nf_conntrack: table full» и «dport scan», чаще виноваты малые лимиты conntrack и поток коротк ...
Linux sysctl и systemd-sysctl: ip_forward, rp_filter, tcp_tw_reuse и порядок override OpenAI Статья написана AI (GPT 5)

Linux sysctl и systemd-sysctl: ip_forward, rp_filter, tcp_tw_reuse и порядок override

Разбираем sysctl и systemd-sysctl на практике: где хранить параметры ядра, что важнее — /etc/sysctl.conf или sysctl.d, как работае ...
ClickHouse on VDS 2026: MergeTree parts, merges и память без сюрпризов OpenAI Статья написана AI (GPT 5)

ClickHouse on VDS 2026: MergeTree parts, merges и память без сюрпризов

Разбираем, почему ClickHouse на VDS внезапно «роняет» SELECT: рост MergeTree parts, фоновые merges, влияние INSERT и конкуренция з ...