Ошибка 504 Gateway Timeout означает одно: веб-сервер принял ваш запрос, передал его дальше — в PHP, приложение или другой сервис — и не дождался ответа за отведённое время. Страница при этом не сломана, база не упала, код не выдал исключение. Просто что-то внутри выполняется дольше лимита, который по умолчанию равен 60 секундам. Лечится это не перезагрузкой сервера, а поиском конкретной операции, которая тормозит, — и такой поиск одинаково устроен и на VPS с nginx, и на общем хостинге.
Материал для тех, кто держит сайт на своём сервере или на виртуальном хостинге и впервые увидел белую страницу с надписью «504 Gateway Time-out». Разберём, чем 504 отличается от соседних кодов и какие таймауты выстроены в цепочку. Дальше — как за несколько команд найти виновника, как поднять лимиты и в каких случаях поднимать их категорически нельзя.
Что означает код 504 и какая программа его отдаёт
504 отдаёт не ваше приложение, а посредник — прокси, который стоит перед приложением. Чаще всего это nginx, реже Apache в режиме прокси, балансировщик или внешний сервис защиты. Посредник открывает соединение к апстриму (так называют программу, которая должна выдать ответ: PHP-FPM, Node.js, Python-приложение), ждёт и в какой-то момент решает, что дальше ждать бессмысленно.
Важная деталь: апстрим в этот момент чаще всего жив. Он не упал и не закрыл соединение — он занят. Скрипт продолжает крутиться и после того, как посетитель уже увидел ошибку, потому что nginx разорвал связь только со своей стороны. Именно поэтому тяжёлый импорт «наполовину проходит»: пользователь получил 504, а данные в базе всё-таки записались.
Роль посредника здесь называется обратным прокси. Таймауты в такой схеме настраиваются дважды — со стороны прокси и со стороны самой программы, и расхождение между этими настройками порождает большинство непонятных 504.
Чем 504 отличается от 502, 500 и 503
Соседние коды пятисотой группы легко перепутать, а лечатся они по-разному. Разница в том, как именно повёл себя апстрим: замолчал, ответил мусором, отказался принимать соединение или честно сообщил об ошибке в коде. Пока вы не определили, какой из четырёх сценариев произошёл, любые правки конфигов — стрельба вслепую.
Быстрый способ различить их: 502 обычно появляется мгновенно, за доли секунды, а 504 — ровно через фиксированный интервал. Если ошибка стабильно вылезает на 60-й секунде ожидания, это почти наверняка сработавший таймаут, а не сбой. Засеките секундомер на первом же повторе — это самая дешёвая диагностика из всех.
| Код | Что произошло с апстримом | Типичная задержка до ошибки | Куда смотреть первым делом |
|---|---|---|---|
| 500 | Приложение отработало и вернуло внутреннюю ошибку | меньше 1 секунды | Лог ошибок PHP или приложения |
| 502 | Апстрим оборвал соединение или отдал испорченный ответ | 0,1–3 секунды | Статус процесса PHP-FPM, нехватка памяти |
| 503 | Все обработчики (воркеры) заняты, очередь переполнена | от 1 секунды | Число процессов и длина очереди |
| 504 | Апстрим жив, но не ответил за отведённое время | ровно 30 или 60 секунд | Медленные запросы, внешние вызовы |
Полную карту статусов, включая четырёхсотую группу, мы собрали в отдельном разборе кодов ошибок HTTP — там же указано, какие из них видит поисковый робот и как они влияют на индексацию.
Какие таймауты выстроены в цепочку запроса
Между браузером и базой данных стоит не один лимит, а четыре или пять. Сработает самый короткий из них, и именно он определит, что увидит посетитель. Поэтому бесполезно поднимать max_execution_time в PHP, если nginx рвёт соединение раньше: пользователь получит 504 в тот момент, когда скрипту оставалось поработать ещё полминуты.
Разберём участников по порядку. Nginx ограничивает ожидание ответа от апстрима: для PHP-FPM это fastcgi_read_timeout, для проксирования на приложение — proxy_read_timeout. PHP-FPM отдельно умеет принудительно убивать зависший процесс через request_terminate_timeout. Сам PHP считает только время работы кода: на многих системах ожидание ответа от базы данных в этот лимит не входит.
| Параметр | Где задаётся | Значение по умолчанию | Что ограничивает |
|---|---|---|---|
proxy_read_timeout |
nginx, секция location | 60 секунд | Паузу между порциями ответа от приложения |
fastcgi_read_timeout |
nginx, секция location для PHP | 60 секунд | Ожидание ответа от PHP-FPM |
request_terminate_timeout |
Пул PHP-FPM | выключен | Жёсткое убийство зависшего процесса |
max_execution_time |
php.ini или код | 30 секунд | Время работы самого PHP-скрипта |
max_input_time |
php.ini | 60 секунд | Приём данных формы и загружаемых файлов |
Отсюда правило: лимит на стороне nginx всегда должен быть чуть больше лимита PHP. Тогда скрипт успеет аккуратно завершиться и вернуть осмысленную ошибку вместо глухого 504.

С чего начать: логи и точное время отказа
Первый слой диагностики — лог ошибок nginx. Он прямо называет виновника и говорит, какой именно таймаут сработал. Откройте его и вызовите проблемную страницу в соседней вкладке.
tail -f /var/log/nginx/error.log
Команда tail -f показывает конец файла и продолжает выводить новые строки по мере их появления. Запись про 504 выглядит как «upstream timed out (110: Connection timed out) while reading response header from upstream» и содержит адрес запроса. Слово «reading» здесь ключевое: оно означает, что соединение установилось, а ответ не пришёл.
Второй слой — понять, все страницы тормозят или одна. Посчитайте, сколько раз за сутки код встречался в логе доступа и по каким URL.
awk '$9 == 504 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
Здесь awk берёт девятое поле строки — это HTTP-код — и печатает седьмое, то есть путь запроса. Дальше пути группируются и сортируются по частоте, а head -20 оставляет двадцать самых частых. Если весь список — это /wp-admin/admin-ajax.php или страница поиска, зона поиска сузилась до одного скрипта.
Как найти медленный запрос к базе данных
Самая частая причина 504 на сайтах с историей — запрос к базе, который перестал укладываться в секунды по мере роста таблиц. Год назад выборка по 5 тысячам строк шла мгновенно, сегодня строк 800 тысяч, индекса нет, и один и тот же код внезапно требует полторы минуты.
В MySQL и MariaDB для этого есть журнал медленных запросов. Включается он без перезапуска сервиса:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
Первая строка включает журнал, вторая задаёт порог: сюда попадут все запросы дольше 1 секунды. Третья указывает файл. Порог в одну секунду для веб-сайта уже критичен — на странице обычно выполняется несколько десятков запросов, и один такой съедает весь бюджет ответа. После воспроизведения ошибки посмотрите файл и найдите строки Query_time с наибольшими значениями.
Дальше нужный запрос прогоняют через EXPLAIN — команду, которая показывает план выполнения. Если в колонке типа доступа стоит ALL, база читает таблицу целиком, и решением будет индекс, а не увеличение таймаута. Не забудьте выключить журнал после диагностики: на нагруженной базе он сам по себе замедляет работу.
Внешние вызовы без таймаута — самая незаметная причина
Второй по частоте сценарий вообще не связан с вашим сервером. Скрипт обращается к чужому сервису: платёжный шлюз, служба доставки, курс валют, отправка письма через внешний SMTP, проверка лицензии плагина. Чужой сервис отвечает медленно или не отвечает совсем, а в коде не выставлен лимит ожидания — и страница висит ровно столько, сколько разрешит операционная система.
Признак такой проблемы характерный: сайт работает нормально, но раз в несколько часов часть страниц отваливается по 504 без всякой связи с нагрузкой. Нагрузка на процессор при этом низкая, а load average в норме — процессы не считают, они ждут.
Проверить гипотезу можно прямо из консоли сервера, замерив ответ подозрительного адреса:
curl -o /dev/null -s -w "%{time_total}n" https://api.example.com/status
Ключ -o /dev/null выбрасывает тело ответа, -s убирает индикатор прогресса, а -w печатает только суммарное время в секундах. Прогоните команду десять раз подряд: если значения скачут от 0,2 до 20 секунд, виновник найден. Лечение — жёсткий лимит ожидания в коде (обычно 3–5 секунд), кеширование ответа и запасное поведение на случай, когда сервис молчит.
Как поднять таймауты правильно: пошагово
Иногда длительная операция действительно легитимна — выгрузка отчёта, пересчёт склада, генерация архива. Тогда лимиты поднимают, но точечно: для одного адреса, а не для всего сайта. Ниже порядок действий на связке nginx плюс PHP-FPM.
- Откройте конфиг сайта в текстовом редакторе:
nano /etc/nginx/sites-available/example.com. Найдите блокlocation ~ .php$, через который идут запросы к PHP. - Добавьте внутрь этого блока строку
fastcgi_read_timeout 300s;— это разрешит ждать ответ до 300 секунд вместо стандартных 60. - Проверьте синтаксис командой
nginx -t. Она читает конфиг и сообщает об ошибке, ничего не применяя. - Примените изменения без разрыва соединений:
systemctl reload nginx. Именно reload, а не restart — перезапуск обрывает активные запросы. - Поднимите лимит PHP до меньшего значения, чем у nginx: в файле
php.iniзадайтеmax_execution_time = 240, чтобы скрипт умирал раньше прокси и успевал записать ошибку в лог. - Перезапустите обработчик:
systemctl restart php8.2-fpm(номер версии подставьте свой), затем повторите проблемную операцию и следите за логом.
Если правки не подействовали, почти всегда причина в том, что изменён не тот файл: на сервере часто лежат несколько конфигов и отдельный php.ini для FPM. Проверить, какой файл реально читается, помогает команда php --ini — она печатает список подключённых файлов настроек. Общая логика правки конфигов подробно расписана в нашем руководстве по настройке nginx.

Почему большой таймаут ломает сайт под нагрузкой
Соблазн выставить 600 секунд и забыть про 504 понятен, но это худшее из решений. Число одновременно работающих обработчиков PHP на сервере ограничено — на конфигурации с 2 ГБ памяти обычно помещается 10–20 процессов. Каждый висящий запрос занимает один процесс целиком, вместе с его долей оперативной памяти.
Дальше арифметика простая. Если тяжёлая страница выполняется 5 минут и её одновременно открыли 15 человек, свободных обработчиков почти не остаётся. Все остальные посетители — включая тех, кто зашёл на главную, — встают в очередь и получают уже не 504, а 502 или 503. Один медленный отчёт кладёт весь сайт.
Поэтому длинный таймаут допустим только для админских адресов и только как временная мера. Для публичных страниц ориентир другой: ответ должен укладываться в 1–2 секунды, а всё дольше 10 секунд — авария, требующая разбора.
Долгие задачи выносят в очередь
Правильное решение для тяжёлых операций — вообще убрать их из веб-запроса. Схема называется фоновой обработкой: страница принимает данные, кладёт задание в очередь и мгновенно отвечает пользователю «принято». Отдельный процесс забирает задание и выполняет его без всяких ограничений по времени, потому что никакой прокси его не ждёт.
Минимальный вариант, доступный на любом сервере, — обычный планировщик. Скрипт импорта запускается не из браузера, а через cron, и работает от имени консольного PHP, где лимит времени по умолчанию отключён совсем:
*/5 * * * * /usr/bin/php8.2 /var/www/example.com/import.php >> /var/log/import.log 2>&1
Первые пять полей строки — это расписание, а запись */5 означает «каждые 5 минут». Двойная стрелка >> дописывает вывод в лог-файл, а 2>&1 отправляет туда же сообщения об ошибках, иначе они потеряются. Пользователю остаётся показать статус задания на странице и обновлять его запросом раз в несколько секунд.
Второй приём — снять с генерации страницы всё, что можно посчитать заранее. Здесь работает кеширование результатов тяжёлых выборок и OPcache, который держит скомпилированный PHP-код в памяти и экономит десятки миллисекунд на каждом запросе.
Когда виноват сервер, а не код
Остаётся случай, когда код нормальный, запросы быстрые, а 504 всё равно приходят пачками в часы пик. Тогда упёрлись в ресурсы: одного ядра и 1 ГБ памяти не хватает, диск не тянет случайное чтение, а сосед по гипервизору — другой виртуальный сервер на той же физической машине — забирает процессорное время. Понять это помогает мониторинг сервера — по графикам сразу видно, совпадают ли всплески ошибок с полкой по процессору или по вводу-выводу.
Переезд на конфигурацию с запасом решает проблему быстрее, чем недели оптимизации, и стоит по нынешним ценам немного. В каталоге собраны 44 площадки. Стартовые тарифы для небольшого сайта выглядят так.
| Провайдер | Стартовая цена | Базовая конфигурация | Тарифов в каталоге |
|---|---|---|---|
| Cloudcore | от 59 ₽/мес | 1 ядро, 1 ГБ RAM, 10 ГБ NVMe | 12 |
| Hosting-Russia | от 99 ₽/мес | стартовые виртуальные серверы | — |
| 4VPS | от 110 ₽/мес | 1 ядро, 1 ГБ RAM, 5 ГБ NVMe | 568 |
| HostVDS | от 127 ₽/мес | 1 ядро, 1 ГБ RAM, 10 ГБ NVMe | 12 |
Данные проверены 04.09.2026.
Для сайта на популярной системе управления берите минимум 2 ядра и 2 ГБ памяти — на таком запасе PHP-FPM держит достаточно процессов, чтобы одна медленная страница не блокировала остальные. Подобрать вариант можно в подборке недорогих VPS, отсортировав по объёму памяти.
Частые ошибки при борьбе с 504
Большинство потерянных часов приходится не на сложную диагностику, а на несколько повторяющихся заблуждений. Разберём их отдельно, чтобы не наступать на те же грабли.
Общий знаменатель у всех пунктов один: ошибку пытаются заглушить, вместо того чтобы измерить. Пока нет цифры «сколько секунд и на каком этапе», любое действие остаётся гаданием.
- Поднимают таймаут до 600 секунд на всём сайте и через неделю получают полную остановку в час пик.
- Правят
php.ini, не заметив, что у PHP-FPM свой файл настроек, и удивляются отсутствию эффекта. - Делают
systemctl restart nginxвместоreloadи обрывают все активные запросы посетителей. - Списывают 504 на хостинг, не открыв ни одного лога и не замерив время ответа.
- Оставляют включённым журнал медленных запросов и добавляют базе лишнюю нагрузку.
- Запускают импорт на 200 тысяч строк из браузера, хотя для этого есть планировщик.
Частые вопросы
Через сколько секунд появляется 504? Обычно ровно через 60 секунд — это значение по умолчанию для proxy_read_timeout и fastcgi_read_timeout в nginx. Если ошибка приходит на 30-й секунде, сработал лимит PHP max_execution_time. Стабильный интервал — главный признак таймаута, а не случайного сбоя.
504 Gateway Time-out — что делать в первую очередь? Откройте лог ошибок nginx и найдите строку со словами upstream timed out: там будет точный адрес проблемного запроса. Затем посчитайте по логу доступа, один это URL или все подряд. Дальнейшие шаги зависят от ответа: одна страница означает медленный код, все страницы — нехватку ресурсов.
Может ли 504 быть виноват хостер, а не мой сайт? Да, если ошибка появляется на статических файлах и главной странице одновременно, а нагрузка на ваш сервер низкая. Тогда проблема выше по цепочке: балансировщик, сеть или защита от атак. В этом случае логи вашего сервера будут почти пустыми, и стоит писать в поддержку с указанием точного времени сбоев.
Влияет ли 504 на позиции в поиске? Разовые ошибки робот переживёт и вернётся позже. Систематические 504 приводят к тому, что страницы выпадают из индекса: робот просто не получает содержимое.
Помогает ли перезагрузка сервера? Иногда помогает на несколько часов, если процессы PHP-FPM зависли на внешнем вызове. Но причина возвращается, обычно в тот же час следующих суток. Перезагрузка нужна только чтобы поднять сайт и спокойно заняться диагностикой.
Чем 504 отличается от 502 на практике? При 502 апстрим оборвал соединение или вернул нечитаемый ответ — ошибка приходит почти мгновенно и часто связана с нехваткой памяти. При 504 апстрим жив и продолжает работать, просто прокси устал ждать. Разное поведение по времени — самый простой способ различить их без логов.
Как понять, что таймаут в коде поднимать нельзя? Посчитайте, сколько одновременных запросов выдержит сервер: разделите доступную память на объём одного процесса PHP. Если операция длится дольше 10 секунд и её могут запустить несколько человек сразу, лимит поднимать нельзя — нужна очередь. Для одиночной админской выгрузки раз в сутки увеличение таймаута допустимо.
Итог
504 Gateway Timeout — не поломка, а сообщение о превышенном лимите ожидания: апстрим жив, но не успевает. Порядок действий всегда один — засечь время до ошибки, найти в логах конкретный адрес, проверить медленные запросы к базе и внешние вызовы, и только потом трогать конфиги. Увеличение таймаута решает проблему на день, вынос долгой задачи в фоновую обработку — навсегда.
Когда причина не в коде, а в упёршихся ресурсах, помогает переезд на конфигурацию с запасом по памяти и процессору. Актуальные тарифы с фильтрами по ядрам, объёму диска и расположению площадки собраны в подборке VPS для сайтов.