#Что означает ошибка
504 Gateway Time-out nginx
Nginx выступает «шлюзом»: принимает запрос и передаёт его приложению — по proxy_pass или fastcgi_pass. Если приложение не ответило за время ожидания (по умолчанию 60 секунд для чтения ответа), Nginx закрывает соединение и отдаёт 504. В отличие от 502 Bad Gateway, где backend отвечает ошибкой или недоступен сразу, при 504 backend жив, но слишком медленный или завис.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Приложение выполняет слишком долгий запросТяжёлая выборка из базы без индекса, большой отчёт, импорт, обращение к медленному внешнему API. | Таймаут возникает на конкретных страницах или действиях, остальные работают быстро. | Найдите медленный запрос (slow log PHP-FPM или базы данных), оптимизируйте; долгие операции вынесите в фон. |
| Backend перегруженВсе рабочие процессы PHP-FPM заняты, новые запросы стоят в очереди и упираются в таймаут. | В журнале PHP-FPM есть server reached pm.max_children; нагрузка на процессор или память высока; тормозит весь сайт. | Проверьте нагрузку, настройки pm.max_children, устраните «зависающие» запросы, при росте трафика добавьте ресурсов. |
| Backend завис или недоступен по сетиСлужба не отвечает, соединение до другого сервера блокируется файрволом, теряются пакеты. | Ошибка на всех страницах; curl до backend с самого сервера не возвращает ответ. | Проверьте службу, файрвол и маршрут до backend; перезапустите зависшую службу. |
| Таймаут стоит на другом звене цепочкиПеред Nginx есть ещё балансировщик, CDN или прокси со своим, более коротким временем ожидания. | Ошибка приходит раньше, чем истекает таймаут Nginx; в error.log Nginx записей нет. | Проверьте и согласуйте таймауты по всей цепочке. |
| Таймаут Nginx меньше реального времени легитимной операцииНекоторые операции (выгрузка, генерация файла) честно занимают дольше минуты. | Операция стабильно выполняется 1–3 минуты, нагрузка в норме. | Осознанно увеличьте таймаут только для нужного location и параллельно подумайте о фоновой обработке. |
#Пошаговая диагностика
- Найдите запись в журнале NginxЧерез SSH откройте журнал Nginx:
sudo tail -n 100 /var/log/nginx/error.logи найдите строку для URL, который вернул 504. Запишите upstream, время,while connectingилиwhile reading response header— это разные причины. 504 означает, что Nginx дождался истечения времени ответа backend, а не обязательно что сам Nginx перегружен. - Определите масштабПроверьте другие страницы того же сайта и соседние сайты, обслуживаемые тем же PHP-FPM/прокси. Если 504 только на тяжёлом поиске или импорте, вероятен медленный запрос; если на всех страницах, смотрите состояние backend и общие ресурсы. Не меняйте все таймауты сразу.
- Проверьте backend и нагрузкуУзнайте из
fastcgi_passилиproxy_pass, какая служба отвечает за запрос, затем проверьте её статус и журнал черезsystemctl/journalctl. Для PHP-FPM проверьтеpm.max_children, очередь, OOM и медленные запросы БД; не перезапускайте весь сервер без выяснения причины. - Проверьте backend напрямуюЕсли backend HTTP доступен напрямую по внутреннему адресу, проверьте его через
curlтолько из доверенной сети с нужным Host. Для PHP-FPM сокета такой тест через HTTP не подходит — проверяйте статус пула и обработку отдельного запроса. Сравните время backend с таймаутом прокси. - При необходимости увеличьте таймаутыЛишь после оценки нормального времени ответа можно изменить
proxy_read_timeout/fastcgi_read_timeoutу нужного маршрута, сохранив конфигурацию и проверивsudo nginx -t. Увеличение ожидания не исправит зависший код; повторите запрос и убедитесь, что backend не держит все воркеры занятыми.
#Шаг 1. Журнал и нагрузка
sudo grep "upstream timed out" /var/log/nginx/error.log | tail -n 20uptimefree -m#Шаг 4. Замер ответа приложения
curl -o /dev/null -s -w "код: %{http_code}, время: %{time_total} с\n" https://ваш-сайт/медленная-страница/#Шаг 5. Увеличение таймаута (если оно оправдано)
fastcgi_* — для PHP-FPM, proxy_* — для proxy_pass. Пути и версия PHP зависят от вашей системы.location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 120s; # было 60s по умолчанию
}
# для проксирования на другое приложение:
# proxy_read_timeout 120s;Также учтите, что PHP останавливает скрипты по max_execution_time, а PHP-FPM — по request_terminate_timeout в конфигурации пула. Если эти значения меньше, чем таймаут Nginx, запрос оборвётся раньше.
sudo nginx -t && sudo systemctl reload nginx#Как проверить результат
- Проблемная страница открывается, а
curlпоказывает приемлемое время ответа. - В
error.logнет новых строкupstream timed out. - Нагрузка на сервер в норме и не растёт при обычном трафике.
#Если не помогло
Включите slow log в PHP-FPM (request_slowlog_timeout и slowlog), чтобы видеть, в каком месте кода зависают запросы, и включите журнал медленных запросов в базе данных. Сопоставьте время событий в журналах Nginx, PHP-FPM и системы. Если перед Nginx есть CDN или балансировщик, проверьте его настройки таймаутов.