
Ошибка 504 Gateway Timeout значит, что сервер на входе (nginx, CDN, защита от DDoS) передал запрос дальше и не дождался ответа за отведённое время. Приложение за ним при этом может быть живо и продолжать считать страницу. Оно просто не успело. Поэтому 504 почти всегда указывает на медленное место: тяжёлый запрос к базе, зависший вызов внешнего сервиса, блокировку таблиц во время импорта.
Чтобы найти причину, нужны три вещи: адреса, на которых появляется 504, время ошибки и журналы медленных запросов за эти минуты. Перезагрузка сервера уберёт ошибку на час, но не найдёт медленный запрос. До «Чёрной пятницы» 27 ноября 2026 года осталось меньше трёх недель, и под нагрузкой медленный шаг первым превращается в 504.
max_execution_time не учитывает время ожидания базы данных и внешних запросов. Скрипт с лимитом 30 секунд может висеть минуту, пока ждёт API доставки.Код описан в стандарте HTTP, RFC 9110, раздел 15.6.5. Смысл определения: сервер, работая как шлюз или прокси, не получил своевременного ответа от сервера выше по цепочке, к которому обращался, чтобы выполнить запрос.
У типичного магазина цепочка выглядит так: браузер → CDN или защита (если есть) → nginx → PHP-FPM → PHP-код → база данных и внешние сервисы. У каждого звена свой предел ожидания:
fastcgi_read_timeout и proxy_read_timeout по умолчанию равны 60 секундам. Тайм-аут действует между двумя последовательными чтениями, а не на весь ответ. Если бэкенд за это время ничего не передал, nginx закрывает соединение и отдаёт 504. У proxy_connect_timeout тоже 60 секунд по умолчанию, и документация отмечает, что больше 75 секунд он обычно быть не может.max_execution_time по умолчанию 30 секунд (в командной строке 0, без ограничения). Руководство PHP предупреждает: время на системные вызовы, потоковые операции и запросы к базе в этот лимит не входит, на Windows это не так. На практике скрипт, который ждёт ответа API, не останавливается по лимиту PHP. Его останавливает только тайм-аут nginx или request_terminate_timeout в PHP-FPM (по умолчанию 0, то есть выключен).Отсюда главный вывод для разбора. 504 сам по себе ничего не говорит о сломанном сервере. Он говорит, что какой-то запрос шёл дольше, чем согласилось ждать звено перед ним.
В ноябре на магазин одновременно давят распродажа 11.11, рассылки перед «Чёрной пятницей», реклама и обмен с 1С, который чаще гоняет цены и остатки. Медленный запрос, который в будни занимал 20 секунд и никому не мешал, под нагрузкой ждёт в очереди к базе и переваливает за минуту. Кроме того, пока PHP-процесс ждёт, он занят. Несколько десятков таких ожиданий занимают весь пул PHP-FPM, и тогда к 504 добавляются 502 на соседних страницах.
Есть и поисковая сторона. В справке Яндекс Вебмастера сказано, что страница с кодом ответа, отличным от 200 OK, недоступна для роботов и посетителей и не может попасть в поиск. Если роботу не удалось подключиться к сайту из-за ошибки сервера, сайт может полностью пропасть из поиска. Инструмент «Проверка ответа сервера» ждёт ответ не дольше трёх секунд, так что медленная страница для него уже ошибка, даже если человек дождётся.
Server. Страница CDN означает, что не дождался CDN, и нужно смотреть, сколько отвечает ваш сервер напрямую. Страница nginx означает, что медленное место за nginx.$request_time и $upstream_response_time, видно, сколько ждал nginx и сколько отвечал бэкенд.request_slowlog_timeout по умолчанию равен 0, журнал выключен. С ним PHP-FPM пишет трассировку стека для запроса, который работает дольше порога. По трассировке видно, на какой функции висит процесс: curl_exec к службе доставки, запрос к базе, генерация PDF.long_query_time по умолчанию 10 секунд. Для разбора порог стоит опустить до 1–2 секунд на время наблюдения.Если сайт не открывается совсем, начните с общего порядка из статьи «Сайт лежит: что делать».
| Источник | Признак | Кто проверяет | Как проверить | Как часто |
|---|---|---|---|---|
| Внешний API без тайм-аута (доставка, оплата, CRM) | 504 только на оформлении или в отдельных шагах | Разработчик | Журнал медленных запросов PHP-FPM, поиск curl_exec и HTTP-клиентов в трассировках |
Перед пиком и при смене подрядчика |
| Тяжёлый запрос к базе (фильтры, поиск, отчёты) | 504 на каталоге с фильтрами или в админке | Разработчик | Журнал медленных запросов MySQL, EXPLAIN для топ-запросов |
Еженедельно в сезон |
| Блокировки таблиц во время импорта | 504 волнами в одно и то же время | Тот, кто отвечает за обмен с 1С | Время ошибок против расписания обмена | После каждого изменения расписания |
| Фоновые задачи внутри запроса покупателя | Случайные медленные страницы без видимой связи с адресом | Разработчик | Агенты Битрикса на хитах или на cron, задачи WP-Cron | Один раз при приёмке сайта и после обновлений |
| Исчерпан пул PHP-FPM | 504 и 502 на всех страницах в пиковые часы | Разработчик или хостинг | Журнал PHP-FPM, страница статуса пула | Перед каждой распродажей |
| Длинные операции в админке (выгрузка, массовое редактирование) | 504 у менеджера, у покупателей всё работает | Разработчик | Перенести операцию в фон или в командную строку | При жалобах менеджеров |
| Тайм-аут CDN короче, чем у сервера | Страница ошибки провайдера, напрямую страница открывается за 70–90 секунд | Владелец аккаунта CDN | Сравнить тайм-ауты CDN и nginx | При подключении CDN |
Команды для первого часа. Пути к журналам зависят от системы и хостинга:
# Какие адреса чаще всего отдают 504 (стандартный формат combined)
awk '$9 == 504 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# В какие минуты были 504: ищем совпадение с импортом и cron
awk '$9 == 504 {print substr($4, 2, 17)}' /var/log/nginx/access.log | uniq -c | tail -30
# Что nginx писал про upstream в эти минуты
grep "upstream timed out" /var/log/nginx/error.log | tail -20
Формат журнала nginx, в котором видно время ответа бэкенда:
log_format timed '$remote_addr [$time_local] "$request" $status '
'rt=$request_time urt=$upstream_response_time';
access_log /var/log/nginx/access_timed.log timed;
Журналы медленных запросов на время наблюдения:
; PHP-FPM, pool.d/www.conf — фрагмент
request_slowlog_timeout = 5s ; по умолчанию 0, журнал выключен
slowlog = /var/log/php-fpm/www-slow.log
request_terminate_timeout = 65s ; по умолчанию 0; чуть дольше, чем ждёт nginx
# MySQL, my.cnf — фрагмент, секция [mysqld]
slow_query_log = 1 ; по умолчанию журнал выключен
long_query_time = 2 ; по умолчанию 10 секунд
slow_query_log_file = /var/log/mysql/slow.log
Тайм-аут на внешний вызов в PHP-коде, пример для cURL:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); // ждать соединения не дольше 3 секунд
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // весь запрос не дольше 10 секунд
// при ошибке показать покупателю запасной вариант: фиксированный тариф, другой способ оплаты
Логика простая. Внешний вызов должен сдаваться раньше PHP-FPM, PHP-FPM раньше nginx, nginx раньше CDN. Тогда ошибку обрабатывает ваш код, и покупатель видит понятное сообщение вместо серой страницы. Увеличивать тайм-аут nginx до пяти минут бесполезно: процесс PHP будет так же занят, а пул закончится быстрее.
Чек-лист на неделю до распродажи:
[ ] Включить журнал медленных запросов PHP-FPM и MySQL, через 2–3 дня разобрать топ-10
[ ] Проверить тайм-ауты всех внешних вызовов на оформлении заказа
[ ] Сверить тайм-ауты CDN, nginx, PHP-FPM и внешних вызовов: каждый следующий короче
[ ] Перенести импорт из 1С, генерацию фидов и выгрузки с пиковых часов
[ ] В Битриксе перевести агенты на cron, в WordPress проверить задачи WP-Cron
[ ] Подготовить запасной вариант для расчёта доставки и оплаты
[ ] Пройти путь покупки до оплаты с телефона через мобильный интернет
[ ] Проверить ключевые страницы в «Проверке ответа сервера» Яндекс Вебмастера
[ ] Назначить дежурного на день распродажи и проверить его доступы
Как найти предел до распродажи, а не во время неё, разобрано в статье «Нагрузочное тестирование сайта перед „Чёрной пятницей“». Про контроль обмена с учётной системой есть отдельная статья: «Мониторинг обмена интернет-магазина с 1С».
Ситуация условная, собрана для иллюстрации.
Магазин на 1С-Битрикс. Менеджеры с утра жалуются, что каталог «тормозит», а около 10:00 и 14:00 покупатели видят 504 на страницах категорий с фильтрами. Главная открывается, проверка доступности главной зелёная. В access.log nginx 504 собраны в двух окнах по 15–20 минут. В журнале медленных запросов MySQL в эти же окна запросы фильтра по свойствам товаров идут по 50–70 секунд, хотя ночью те же запросы выполняются за секунду. В расписании обмена с 1С полная выгрузка цен и остатков стоит на 10:00 и 14:00.
Что сделали. Полную выгрузку перенесли на ночь, днём оставили выгрузку изменений. Агенты, которые шли на хитах, перевели на cron. 504 в дневные часы пропали. Разработчик после распродаж займётся индексами для фильтров, потому что под нагрузкой те же запросы всё равно идут медленнее нормы. Вывод для команды: 504 по расписанию ищут в расписании, а не в железе.
max_execution_time. В Linux он не останавливает скрипт, который ждёт базу или внешний сервис. Нужны тайм-ауты в самих вызовах и request_terminate_timeout.Ограничения. Команды и фрагменты выше подходят для своего сервера или VPS со связкой nginx и PHP-FPM. На виртуальном хостинге часть настроек меняет только хостинг: начните разговор с адресов страниц, времени ошибок и просьбы включить журнал медленных запросов. На Tilda и InSales сайт работает на инфраструктуре платформы, при 504 там проверяют статус платформы и пишут в поддержку. Никакие настройки не гарантируют, что 504 не повторится. Они помогают узнать медленное место заранее и найти причину за минуты.
Код 504 формирует сервер или посредник, а не браузер. Если сайт не отвечает только у вас, причина может быть в корпоративном прокси или VPN, которые тоже работают как шлюз и отдают свой 504. Проверьте страницу из другой сети, например с мобильного интернета.
502 значит, что посредник получил от бэкенда неверный ответ или соединение оборвалось. 504 значит, что бэкенд не ответил вовремя. 502 чаще указывает на упавший или убитый процесс, 504 на медленный код, базу или внешний сервис.
Можно на время, для одной известной долгой операции в админке, и лучше на отдельном адресе. Для страниц покупателя это не решение: страница, которая отвечает больше минуты, теряет покупателя и не проходит проверку робота Яндекса. Медленную операцию стоит ускорить или перенести в фон.
proxy_read_timeout, proxy_connect_timeout, proxy_send_timeout): https://nginx.org/en/docs/http/ngx_http_proxy_module.htmlfastcgi_read_timeout): https://nginx.org/en/docs/http/ngx_http_fastcgi_module.htmlset_time_limit (что не входит в лимит времени): https://www.php.net/manual/en/function.set-time-limit.phpmax_execution_time: https://www.php.net/manual/en/info.configuration.php#ini.max-execution-timerequest_slowlog_timeout, request_terminate_timeout): https://www.php.net/manual/en/install.fpm.configuration.phpПроверено: 9 ноября 2026 года.
Шаг «узнать о 504 раньше покупателей» можно автоматизировать. Pingvera раз в минуту проверяет доступность сайта по HTTP из нескольких регионов, подтверждает сбой повторными проверками и присылает алерт в Telegram, MAX, VK, на почту или в webhook. Для WooCommerce сервис следит и за потоком заказов: если страницы открываются, а заказы перестали приходить, придёт отдельный алерт. Бесплатный тариф покрывает до 5 сайтов, разовую проверку можно сделать без регистрации на https://pingvera.ru/check.
Pingvera следит за сайтами клиентов «снаружи и изнутри» — доступность из регионов, формы, оплата, домен, SSL, сервер — и предупреждает в Telegram, email и Max раньше, чем напишет клиент.
Попробовать Pingvera бесплатноЧитайте также: Ошибка 502 на сайте: причины и что делать магазину · Ошибка 403 на сайте: что значит и что делать магазину · Ошибка 404 на сайте: что значит и что делать магазину · Ошибка 503 на сайте: что значит и что делать · Бесплатно проверить сайт.