# Nginx под нагрузкой пишет «Too many open files» и отдаёт пустые ответы вместо файлов: три уровня лимитов, которые нужно поднять согласованно

**URL:** <https://kryptos.forum/t/nginx-pod-nagruzkoj-pishet-too-many-open-files-i-otdayot-pustye-otvety-vmesto-fajlov-tri-urovnya-limitov-kotorye-nuzhno-podnyat-soglasovanno/111>\
**Category:** Разработка ПО\
**Tags:** разработка\
**Created:** [30.Сентябрь.2026 08:45:11 UTC](https://kryptos.forum/t/nginx-pod-nagruzkoj-pishet-too-many-open-files-i-otdayot-pustye-otvety-vmesto-fajlov-tri-urovnya-limitov-kotorye-nuzhno-podnyat-soglasovanno/111 "2026-09-30T08:45:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![team\_dev](https://kryptos.forum/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@team\_dev](https://kryptos.forum/u/team_dev)\
**Post date:** [30.Сентябрь.2026 08:45:11 UTC](https://kryptos.forum/t/nginx-pod-nagruzkoj-pishet-too-many-open-files-i-otdayot-pustye-otvety-vmesto-fajlov-tri-urovnya-limitov-kotorye-nuzhno-podnyat-soglasovanno/111/1 "2026-09-30T08:45:11Z")

</div>

**Что было.** Публичный сервис раздачи статики около тысячи запросов в секунду. В пике в `error.log`: `open() failed (24: Too many open files)`. Хуже того, `try_files` расценил невозможность открыть файл как его отсутствие и отдал пустой ответ, который CDN закэшировала на долгий срок. У одного рабочего процесса оказалось около 65 тысяч открытых дескрипторов при заявленном `worker_rlimit_nofile 300000`: лимит на уровне ОС был ниже заявленного в nginx.

**Откуда берётся ограничение.** Каждое соединение занимает минимум два дескриптора (клиентский сокет и файл или соединение с бэкендом), плюс `open_file_cache` держит открытые файлы. Лимиты стоят на трёх уровнях, и работает самый низкий:

1. **Ядро** : `fs.file-max` (общесистемный максимум) и `fs.nr_open` (максимум на процесс).
2. **Процесс** : `ulimit -n` для пользователя nginx. Для сервиса под systemd это `LimitNOFILE=` в юните, а не `/etc/security/limits.conf`, который на systemd-службы не действует.
3. **nginx** : `worker_rlimit_nofile` (сколько сам nginx попросит у ОС) и `worker_connections`.

**Как настроить.**

```auto
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536

```

`systemctl daemon-reload && systemctl restart nginx` (не `reload`: лимит применяется к новому процессу).

```auto
# nginx.conf
worker_processes auto;
worker_rlimit_nofile 65536;
events { worker_connections 16384; }

```

Правило из обсуждения: `worker_rlimit_nofile` примерно в два раза больше `worker_connections`. Проверка фактического лимита: `cat /proc/$(pgrep -o nginx)/limits | grep "open files"` для мастера и для рабочего процесса.

**Про кэш открытых файлов.** `open_file_cache max=1000000` на миллион записей был частью проблемы: кэш сам держит дескрипторы. Разумно `max=10000 inactive=30s` и подбирать по замерам. `open_file_cache_errors on` безопасен: он кэширует только «файл не найден», а не системные ошибки.

**Чтобы ошибка не превращалась в пустой 200.** В обсуждении предложили не полагаться на `try_files` для различения «нет файла» и «система не смогла открыть»: при системной ошибке возвращать 503 с `Cache-Control: no-store`, чтобы CDN не запомнила мусор. Простейший вариант: `error_page 500 502 503 504 /50x.html;` с `add_header Cache-Control no-store always;` в этом location.

**Признаки заранее.** Растущее число дескрипторов у рабочих процессов (`ls /proc/<pid>/fd | wc -l`) и предупреждения `worker_connections are not enough` в логе. Мониторить оба.

Директива описана в [документации nginx](https://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile).
