pm.max_children ограничивает число одновременных PHP-FPM-процессов. Когда все заняты, новые запросы ждут в очереди; клиент может увидеть 502, 503 или 504 в зависимости от прокси и характера отказа. Сначала подтвердите насыщение пула по статусу и логам, затем рассчитывайте лимит из доступной памяти и нагрузки на БД.

Фраза «502 от PHP-FPM» описывает симптом на стороне шлюза, а не прямой код PHP-FPM. nginx общается с FPM по FastCGI; он может вернуть 502, если соединение разорвано или ответ некорректен, и 504 при ожидании. Смотрите, кто выдал код, по разбору 5xx. Настройки пула определены в документации PHP-FPM.
Проверьте очередь и процессный лимит
| Сигнал | Где смотреть | Что значит |
|---|---|---|
max children reached | FPM error.log или status page | Пул достиг лимита хотя бы раз |
listen queue | FPM status page | Запросы ждут свободный процесс сейчас |
active processes | FPM status page | Занятые процессы в момент снимка |
upstream timed out | nginx error.log | Нужно установить фазу и причину ожидания |
Страница FPM status может показывать listen queue, max listen queue и max children reached. Не выставляйте её публично: она раскрывает внутреннее состояние и URL запросов в полном режиме. При pm = dynamic дополнительно проверьте pm.start_servers, pm.min_spare_servers и pm.max_spare_servers; при ondemand важны задержка запуска процесса и idle timeout. Медленная БД может держать воркеры занятыми даже при достаточном лимите.

Считайте лимит от доступной памяти
Упрощённая верхняя граница: floor(память_для_FPM / память_одного_воркера). Например, если после резерва под ОС, nginx и БД остаётся 2 ГиБ, а рабочий PHP-процесс на реальной нагрузке занимает около 100 МиБ, стартовая оценка — 20 процессов. Это учебный расчёт, не измерение enterno.io и не готовый лимит: память процесса меняется между запросами; общие страницы в RSS могут считаться повторно. Для оценки собственного пула снимите распределение PSS/USS под нагрузкой, а не один idle RSS.
ps -eo pid,rss,cmd | grep '[p]hp-fpm'
# Linux: smem -P 'php-fpm' -c 'pid pss uss command' (если smem установлен)
# В пуле: pm.status_path = /fpm-status — доступ только из внутренней сети.
# Сопоставьте listen queue и max children reached с моментом 5xx.
После расчёта убедитесь, что БД, Redis и внешние API выдержат столько параллельных запросов. Увеличение pm.max_children без памяти приведёт к OOM и более тяжёлым 502. В nginx проверьте fastcgi_connect_timeout и fastcgi_read_timeout; read timeout считает паузу между чтениями. Общий порядок анализа описан в разборе upstream timed out.
Отделите FPM от других причин 502
Проверьте существование Unix-сокета и права nginx на него, правильность fastcgi_pass, состояние процесса и его рестарты. Connection refused указывает на недоступный адрес или сокет, а upstream prematurely closed connection — на закрытие после установки связи; оба требуют дополнительных логов. Рост очереди без падения процессов указывает на нагрузку или долгие запросы. Если при том же времени есть 5xx на внешнем CDN, сопоставьте TTFB и полное время с внутренним request ID.
Как сделан материал
Поля статуса и директивы сверены с руководством PHP, реакция nginx — с FastCGI-модулем. Пример с 2 ГиБ и 100 МиБ явно модельный; замеров памяти пула enterno.io в статье нет. На enterno.io используется отдельная конфигурация Apache, поэтому её прежний лимит воркеров нельзя подставлять в расчёт FPM. SerpAPI дал RU/EN выдачу, Wordstat региона 225 не вернул оценку точной фразы и показал 2 для php fpm 502.
Частые вопросы
Почему max children reached есть, а 502 нет?
Краткий пик может поместиться в очереди и завершиться до таймаута. Сопоставьте время и глубину очереди.
Достаточно увеличить pm.max_children?
Нет. Проверьте доступную память, длительность запросов и ограничения зависимостей.
Чем 502 отличается от 504 в этом случае?
502 обычно связан с непригодным ответом или обрывом, 504 — с истечением ожидания на шлюзе; конкретный слой надо проверить.
Можно ли открыть FPM status наружу?
Не следует. Ограничьте доступ и при необходимости собирайте метрики через защищённый внутренний путь.