Ошибка 504 Gateway Timeout: что означает и как исправить

Автор: Опубликовано: 8 минут чтения

504 Gateway Timeout означает, что промежуточный сервер (шлюз) передал запрос дальше, но не получил ответ за отведённое время и прервал ожидание. Проблема почти всегда во времени обработки: медленный скрипт, тяжёлый запрос к базе, зависший внешний API или нехватка свободных обработчиков. Посетителю обычно достаточно подождать и обновить страницу, владельцу сайта нужно проверить логи и согласовать таймауты на всех уровнях.

Ошибка 504 Gateway Timeout: что означает и как исправить
Схема: где возникает ошибка 504 Цепочка запроса: Браузер → nginx → PHP-FPM → MySQL. Сбой между узлами «nginx» и «PHP-FPM». Браузер nginx PHP-FPM MySQL Ошибка 504 Ответ с кодом ошибки возвращает узел «nginx»
Ошибка 504 Gateway Timeout: что означает и как исправить: путь запроса и место сбоя.
Содержание
  1. Что означает ошибка 504 простыми словами
  2. Чем 504 отличается от похожих кодов
  3. Причины ошибки
  4. Что делать посетителю
  5. Что делать владельцу сайта или разработчику
  6. Как предотвратить повторение
  7. Если 504 встречается не в браузере

Коротко: как устранить ошибку 504 на своём сайте

  1. Найдите звено, где рвётся запрос. Сравните время ответа напрямую к бэкенду и через прокси: curl -sS -o /dev/null -w "code:%{http_code} ttfb:%{time_starttransfer} total:%{time_total}\n" https://site.ru/page. Если бэкенд отвечает быстро, а через шлюз приходит 504 — смотрите настройки прокси и таймауты; если медленно везде — проблема в приложении, базе или внешнем сервисе.
  2. Прочитайте логи nginx и PHP-FPM. Ищите в /var/log/nginx/error.log строки вида "upstream timed out (110: Connection timed out) while reading response header from upstream". В access.log добавьте в log_format переменные $request_time и $upstream_response_time — они показывают, сколько ждали бэкенд. Для PHP-FPM смотрите journalctl -u php8.2-fpm и slowlog.
  3. Согласуйте таймауты на всех уровнях. В nginx задайте proxy_connect_timeout 10s, proxy_send_timeout 120s, proxy_read_timeout 120s, fastcgi_read_timeout 120s. В PHP поднимите max_execution_time и request_terminate_timeout до сопоставимых значений. Внешний слой (CDN, балансировщик) должен ждать дольше внутреннего, иначе он будет обрывать запросы, которые бэкенд ещё мог бы завершить.
  4. Проверьте пул обработчиков. Если все процессы PHP-FPM заняты, новые запросы стоят в очереди и упираются в таймаут. Смотрите pm.max_children, число процессов (ps aux | grep php-fpm | wc -l), включите страницу статуса и request_slowlog_timeout = 5s, чтобы видеть конкретные медленные вызовы.
  5. Найдите медленный код и внешние вызовы. Включите slow query log MySQL, проверьте SHOW FULL PROCESSLIST, для WordPress — Query Monitor и wp db query "SHOW FULL PROCESSLIST;". Всем исходящим запросам (curl, Guzzle, axios, PDO) задайте явные таймауты, иначе один недоступный API держит воркер десятки секунд.
  6. Вынесите долгие операции из HTTP-запроса. Импорт, резервное копирование, генерация отчётов и рассылки должны выполняться в фоновой очереди (Redis, RabbitMQ, cron-воркеры), а запрос — сразу отдавать 202 и статус выполнения. Дополнительно настройте мониторинг доступности с проверкой каждые 1–5 минут и алерты по коду 504 и времени ответа.

Что означает ошибка 504 простыми словами

504 Gateway Timeout (дословно — «время ожидания шлюза истекло») означает, что запрос принял промежуточный сервер — шлюз, — передал его дальше, но за отведённое время ответа не получил и прервал ожидание.

Типичная цепочка: браузер → nginx или Apache → PHP-FPM, Node.js, приложение → база данных или внешний сервис. Не уложиться в лимит может любое звено. Сам шлюз при этом исправен: он честно отвечает браузеру кодом 504 и сообщает, что «дальше» не ответило.

Ключевое: 504 — почти всегда про время, а не про синтаксис, права доступа или отсутствующий файл. Скрипт, который вчера отрабатывал за две секунды, сегодня может не укладываться в минуту — из-за выросшей таблицы в базе, зависшего внешнего API или нехватки свободных обработчиков.

Как ошибка выглядит в браузерах

  • Текст страницы формирует сервер, поэтому варианты разные: «504 Gateway Time-out», «504 Gateway Timeout», «Время ожидания истекло».
  • В Chrome, Edge, Яндекс Браузере и других браузерах на Chromium чаще показывается стандартная страница nginx; если её отключили, можно увидеть пустой экран.
  • В Safari на iPhone и в мобильных браузерах на Android сообщение бывает короче — «Сервер не отвечает», «Не удалось открыть страницу».
  • Отличить 504 от потери связи просто: интернет работает, другие сайты открываются, а конкретная страница стабильно отдаёт ошибку шлюза.
  • Встроенный браузер внутри мессенджера или мобильного приложения иногда не показывает код вовсе — только «что-то пошло не так».

Чем 504 отличается от похожих кодов

Код Что означает Типичная причина
500 Internal Server Error Приложение упало при обработке Ошибка в коде, необработанное исключение
502 Bad Gateway Шлюз получил от бэкенда неверный или пустой ответ Процесс упал, не тот порт, сокет недоступен
503 Service Unavailable Сервис недоступен целиком Перегрузка, обслуживание, нехватка воркеров
504 Gateway Timeout Ответ не пришёл вовремя Медленный скрипт, запрос к базе, внешний API
408 Request Timeout Клиент не отправил запрос целиком Очень медленный канал

На практике: 502 — бэкенд «ответил неправильно» или не ответил сразу, 504 — ответа нет слишком долго. Подробнее про соседние коды — в материалах про ошибку 502, ошибку 503 и ошибку 500. Отдельно стоит знать про 499 в логах nginx: это не стандарт, а внутренняя пометка «клиент закрыл соединение сам» — часто как раз после того, как пользователь устал ждать.

Причины ошибки

Для посетителя

Для вас причина обычно одна из трёх: на сайт пришло больше запросов, чем он выдерживает; открываемая страница выполняет тяжёлую операцию (отчёт, выгрузка, импорт, поиск по большой базе); сайт зависит от внешнего сервиса — платёжного шлюза, капчи, карт, рассылки, — который сейчас отвечает медленно. В редких случаях виноват посредник: корпоративный прокси, VPN, антивирус с проверкой HTTPS или CDN, через который сайт раздаётся.

Для владельца сайта

  • Скрипт работает дольше таймаута: импорт товаров, генерация PDF или Excel, резервное копирование, синхронизация с 1С, парсинг.
  • Медленные запросы к базе: нет индексов, блокировки, тяжёлые JOIN, разросшиеся таблицы логов и метаданных.
  • Исчерпан пул PHP-FPM или воркеров приложения — новые запросы стоят в очереди и упираются в лимит.
  • Внешний вызов выполняется без таймаута и держит обработчик, пока удалённый сервис не ответит или не оборвёт соединение.
  • Заниженные таймауты nginx, Apache или CDN при нормальном времени обработки.
  • Сетевые проблемы между узлами: DNS, MTU, отбрасывание пакетов файрволом, «залипшие» постоянные соединения.

Если задача собирает данные с чужих страниц, таймауты особенно часты — общие подходы разобраны в статье про парсинг сайтов.

Что делать посетителю

  1. Обновить страницу: F5, а при подозрении на кэш — Ctrl+F5 (на macOS — Cmd+Shift+R).
  2. Подождать минуту-две и попробовать снова — многие сбои кратковременные.
  3. Проверить другие сайты. Если не открывается ничего, дело в вашем подключении, а не в сайте.
  4. Попробовать другую сеть или браузер: мобильный интернет вместо Wi-Fi, режим инкогнито без расширений.
  5. Отключить VPN, прокси и фильтрацию HTTPS в антивирусе, если ошибка повторяется только на одном сайте.
  6. Не отправлять форму или оплату по десять раз: часть запросов могла дойти до сервера, и операция способна продублироваться.
  7. Для больших файлов использовать менеджер загрузок с докачкой, чтобы не начинать скачивание заново.

Что делать владельцу сайта или разработчику

Шаг 1. Локализовать звено

Сначала выясните, где теряется время — на входе или внутри. Замер извне:

curl -sS -o /dev/null -w "code:%{http_code} dns:%{time_namelookup} connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://example.com/slow-page

Затем то же самое локально, минуя прокси, — прямо в сокет или порт приложения:

curl -sS -o /dev/null -w "code:%{http_code} total:%{time_total}\n" http://127.0.0.1:8080/slow-page

Если локально быстро, а снаружи 504 — смотрите прокси, CDN и балансировщик. Если медленно везде — копайте приложение.

Шаг 2. Прочитать логи

grep -i "upstream timed out" /var/log/nginx/error.log | tail -n 20
grep -iE "(request_time|upstream_response_time)" /var/log/nginx/access.log | tail -n 20
journalctl -u php8.2-fpm -n 100 --no-pager

Формулировки nginx подсказывают стадию: while reading response header from upstream — бэкенд не начал отвечать; while connecting to upstream — не удалось установить соединение; upstream timed out вместе с SSL_do_handshake — проблема на стороне внешнего сервиса. Чтобы видеть цифры, добавьте в log_format переменные $request_time и $upstream_response_time.

Шаг 3. Согласовать таймауты в nginx

location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_read_timeout 120s;
    include fastcgi_params;
}

location /api/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_connect_timeout 10s;
    proxy_send_timeout 120s;
    proxy_read_timeout 120s;
    proxy_buffering off;
}

Проверка и перезагрузка: nginx -t && systemctl reload nginx. Помните: поднять таймаут — временная мера. Если запрос стал занимать три минуты вместо трёх секунд, вы просто дольше держите пользователя и воркер.

Шаг 4. Проверить PHP-FPM

pm = dynamic
pm.max_children = 25
pm.start_servers = 5
pm.max_requests = 500
request_terminate_timeout = 120s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log

Если все дочерние процессы заняты (ps aux | grep php-fpm | wc -l близко к pm.max_children), запросы ждут в очереди и получают 504, даже когда код быстрый. Slowlog покажет конкретные функции, а страница статуса (pm.status_path) — очередь и среднее время обработки. Ориентируйтесь на объём памяти сервера: каждому процессу нужна своя доля.

Шаг 5. Настройки Apache

Timeout 120
ProxyTimeout 120

<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>

В error_log ищите записи proxy: FCGI и timeout. Для диагностики пригодится mod_status — он показывает, какие запросы сейчас выполняются и сколько висят.

Шаг 6. WordPress

  • Тяжёлые операции (бэкап, импорт, обновление тысяч товаров, экспорт заказов) выносите в очередь или выполняйте через WP-CLI, а не через браузер.
  • wp-cron.php, запускаемый на каждом запросе, добавляет нагрузку. Отключите его в wp-config.php строкой define('DISABLE_WP_CRON', true); и настройте системный cron: */5 * * * * wp cron event run --due-now --path=/var/www/site >/dev/null 2>&1.
  • Проверьте плагины: wp plugin list, затем отключайте подозрительные по одному. Для профилирования подойдёт Query Monitor.
  • Долгие запросы к базе ищите через wp db query "SHOW FULL PROCESSLIST;" и slow query log MySQL.

Шаг 7. Node.js

const http = require('http');
const server = http.createServer(app);

server.headersTimeout = 65_000;
server.requestTimeout = 300_000;
server.keepAliveTimeout = 65_000;

Проверьте таймауты в клиентах: timeout у axios, headersTimeout и bodyTimeout у undici, AbortController для fetch. Долгие задачи (обработка видео, рассылка, сборка отчёта) переводите в очередь и отвечайте сразу: 202 Accepted и отдельный адрес для статуса. Для SSE и WebSocket в nginx нужны proxy_read_timeout и proxy_buffering off, иначе поток оборвётся молча.

Шаг 8. База данных и внешние сервисы

SHOW FULL PROCESSLIST;
SHOW ENGINE INNODB STATUS;

Долгие запросы ищутся медленным логом MySQL, блокировки — в выводе InnoDB. Всем исходящим вызовам задайте явный лимит: CURLOPT_TIMEOUT, timeout в Guzzle и HTTP-клиентах, PDO::ATTR_TIMEOUT для подключения. Один недоступный сервис без таймаута способен положить весь сайт: обработчики заняты ожиданием, остальные посетители получают 504.

Как предотвратить повторение

  • Мониторинг доступности. Внешние проверки раз в 1–5 минут (UptimeRobot, Zabbix, Prometheus с Blackbox exporter) плюс алерты на код 504 и на рост времени ответа. Внутренний мониторинг без внешней проверки не увидит проблемы CDN и сети.
  • Логи и метрики. Храните $request_time и $upstream_response_time, смотрите не среднее, а 95-й и 99-й процентили: именно они превращаются в 504. Настройте ротацию, чтобы диск не закончился.
  • Лимиты и очередь. Ограничивайте число одновременных тяжёлых запросов (limit_req в nginx), держите pm.max_children в соответствии с памятью, ставьте долгие задачи в очередь с воркерами и повторами.
  • Согласованность таймаутов. Таймаут внешнего слоя должен быть больше внутреннего: клиент < CDN < nginx < PHP-FPM < внешний вызов. Иначе верхний слой обрывает работу, которую нижний ещё мог завершить.
  • Кэширование. Кэш страниц и CDN для статики снимают нагрузку с приложения и уменьшают вероятность очередей в пиковые часы.
  • Проверки после изменений. Нагрузочный тест и проверка ключевых сценариев (оформление заказа, оплата, вход) после обновления плагинов, CMS или конфигов — типичный источник внезапных 504.

Если 504 встречается не в браузере

Числовые коды вида 504 в мобильных играх, приложениях и бортовых компьютерах автомобилей — это внутренние коды конкретного продукта, они не связаны с протоколом HTTP и с работой сайта. Расшифровку в таких случаях даёт документация приложения, форум разработчика или сервисная книжка автомобиля.

Частые вопросы

Ошибка 504 — это проблема моего компьютера или телефона?

Почти всегда это проблема на стороне сайта: устройство и интернет работают, другие страницы открываются. Код 504 формирует сервер, когда не дождался ответа от своего бэкенда. Ваша сторона важна редко — например, если между вами и сайтом стоит корпоративный прокси или антивирус с фильтрацией HTTPS.

Сколько ждать, пока сайт заработает после ошибки 504?

Обычно от нескольких секунд до нескольких минут: шлюз перезапускает обработчик или нагрузка спадает. Если одна и та же страница отдаёт 504 часами и сутками, дело не в случайном всплеске, а в постоянной причине — тяжёлом скрипте, отсутствии индексов в базе или зависшем внешнем API.

Чем 504 отличается от 502 и 503?

502 значит, что шлюз получил от бэкенда неверный или пустой ответ (часто процесс упал или слушает другой порт). 503 говорит, что сервис недоступен целиком — обслуживание или перегрузка. 504 означает, что ответа не было слишком долго. На практике 502 и 504 часто идут рядом: при падении обработчиков часть запросов обрывается сразу, часть — по таймауту.

Почему 504 появляется только на одной странице сайта?

Значит, именно этот обработчик выходит за лимит времени: отчёт, выгрузка в Excel, импорт, страница с внешним виджетом или тяжёлым запросом к базе. Остальные страницы укладываются в таймаут. Владельцу стоит профилировать конкретный сценарий, а не поднимать таймауты всему сайту.

Влияет ли 504 на позиции в поиске?

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

Может ли 504 возникнуть из-за настроек CDN или балансировщика?

Да. Если таймаут на CDN или балансировщике меньше, чем время обработки запроса на сервере, внешний слой оборвёт соединение первым и покажет пользователю свою страницу 504, хотя бэкенд продолжал считать ответ. Проверьте, что таймауты растут от внутреннего слоя к внешнему.

Материал подготовлен редакцией справочника Торох и носит справочный характер: интерфейсы программ и настройки серверов зависят от версии. Нашли неточность? Напишите нам.

Читайте также

Другие разделы