Ошибка 504 Gateway Timeout: что означает и как исправить
504 Gateway Timeout означает, что промежуточный сервер (шлюз) передал запрос дальше, но не получил ответ за отведённое время и прервал ожидание. Проблема почти всегда во времени обработки: медленный скрипт, тяжёлый запрос к базе, зависший внешний API или нехватка свободных обработчиков. Посетителю обычно достаточно подождать и обновить страницу, владельцу сайта нужно проверить логи и согласовать таймауты на всех уровнях.
Содержание
Коротко: как устранить ошибку 504 на своём сайте
- Найдите звено, где рвётся запрос. Сравните время ответа напрямую к бэкенду и через прокси: curl -sS -o /dev/null -w "code:%{http_code} ttfb:%{time_starttransfer} total:%{time_total}\n" https://site.ru/page. Если бэкенд отвечает быстро, а через шлюз приходит 504 — смотрите настройки прокси и таймауты; если медленно везде — проблема в приложении, базе или внешнем сервисе.
- Прочитайте логи 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.
- Согласуйте таймауты на всех уровнях. В 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, балансировщик) должен ждать дольше внутреннего, иначе он будет обрывать запросы, которые бэкенд ещё мог бы завершить.
- Проверьте пул обработчиков. Если все процессы PHP-FPM заняты, новые запросы стоят в очереди и упираются в таймаут. Смотрите pm.max_children, число процессов (ps aux | grep php-fpm | wc -l), включите страницу статуса и request_slowlog_timeout = 5s, чтобы видеть конкретные медленные вызовы.
- Найдите медленный код и внешние вызовы. Включите slow query log MySQL, проверьте SHOW FULL PROCESSLIST, для WordPress — Query Monitor и wp db query "SHOW FULL PROCESSLIST;". Всем исходящим запросам (curl, Guzzle, axios, PDO) задайте явные таймауты, иначе один недоступный API держит воркер десятки секунд.
- Вынесите долгие операции из 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, отбрасывание пакетов файрволом, «залипшие» постоянные соединения.
Если задача собирает данные с чужих страниц, таймауты особенно часты — общие подходы разобраны в статье про парсинг сайтов.
Что делать посетителю
- Обновить страницу: F5, а при подозрении на кэш — Ctrl+F5 (на macOS — Cmd+Shift+R).
- Подождать минуту-две и попробовать снова — многие сбои кратковременные.
- Проверить другие сайты. Если не открывается ничего, дело в вашем подключении, а не в сайте.
- Попробовать другую сеть или браузер: мобильный интернет вместо Wi-Fi, режим инкогнито без расширений.
- Отключить VPN, прокси и фильтрацию HTTPS в антивирусе, если ошибка повторяется только на одном сайте.
- Не отправлять форму или оплату по десять раз: часть запросов могла дойти до сервера, и операция способна продублироваться.
- Для больших файлов использовать менеджер загрузок с докачкой, чтобы не начинать скачивание заново.
Что делать владельцу сайта или разработчику
Шаг 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, хотя бэкенд продолжал считать ответ. Проверьте, что таймауты растут от внутреннего слоя к внешнему.
Материал подготовлен редакцией справочника Торох и носит справочный характер: интерфейсы программ и настройки серверов зависят от версии. Нашли неточность? Напишите нам.
Читайте также
- Ошибка 403 Forbidden: что это значит и как исправить
- Ошибка 404: страница не найдена — что это значит и как исправить
- Ошибка 500 (Internal Server Error): что это значит и как исправить
- Ошибка 502 Bad Gateway: что это значит и как исправить
- Ошибка 502 Bad Gateway в nginx: причины и способы исправления
- Ошибка 503 (Service Unavailable): что это значит и как исправить