Как исправить ошибку 504 Gateway Timeout на сервере

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

Марина
Марина
📅 30 сентября 2026
Как убрать ошибку 504 Gateway Timeout на своём сервере

Ошибка 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.

Цепочка таймаутов веб-сервера и PHP при ошибке 504 Gateway Timeout
Сработает самый короткий лимит, поэтому значение на стороне nginx держат выше, чем у PHP: тогда скрипт успеет вернуть внятную ошибку.

С чего начать: логи и точное время отказа

Первый слой диагностики — лог ошибок 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.

  1. Откройте конфиг сайта в текстовом редакторе: nano /etc/nginx/sites-available/example.com. Найдите блок location ~ .php$, через который идут запросы к PHP.
  2. Добавьте внутрь этого блока строку fastcgi_read_timeout 300s; — это разрешит ждать ответ до 300 секунд вместо стандартных 60.
  3. Проверьте синтаксис командой nginx -t. Она читает конфиг и сообщает об ошибке, ничего не применяя.
  4. Примените изменения без разрыва соединений: systemctl reload nginx. Именно reload, а не restart — перезапуск обрывает активные запросы.
  5. Поднимите лимит PHP до меньшего значения, чем у nginx: в файле php.ini задайте max_execution_time = 240, чтобы скрипт умирал раньше прокси и успевал записать ошибку в лог.
  6. Перезапустите обработчик: systemctl restart php8.2-fpm (номер версии подставьте свой), затем повторите проблемную операцию и следите за логом.

Если правки не подействовали, почти всегда причина в том, что изменён не тот файл: на сервере часто лежат несколько конфигов и отдельный php.ini для FPM. Проверить, какой файл реально читается, помогает команда php --ini — она печатает список подключённых файлов настроек. Общая логика правки конфигов подробно расписана в нашем руководстве по настройке nginx.

Поиск причины ошибки 504 по логам: строка таймаута и частые адреса
Список адресов из лога сразу сужает зону поиска: если все отказы приходятся на один скрипт, дело в нём, а не в ресурсах сервера.

Почему большой таймаут ломает сайт под нагрузкой

Соблазн выставить 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 для сайтов.

Поделиться:
👁 79 просмотров
Марина
Редактор · FREEHOSTING
Главный редактор FREEHOSTING. С 2020 года тестирует VDS, VPS и хостинг-провайдеров — арендует серверы, нагружает их реальными проектами и пишет честные обзоры по итогам. Помогает читателям выбирать хостинг под свои задачи: от Telegram-бота до production-сайта.