Skip to content

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

HTTP 504 Gateway Timeout — ошибка прокси-сервера. Nginx (или другой реверс-прокси) ждал ответа от приложения слишком долго и сдался. По смыслу очень близка к 502 Bad Gateway, но с одним важным отличием: при 504 приложение отвечает, но слишком медленно.

  • 🚨 Сайт показывает «504 Gateway Timeout»
  • 🔍 Причина — приложение слишком долго обрабатывает запрос
  • 🛠️ Чинится оптимизацией приложения или увеличением timeout прокси
  • ⏱️ По умолчанию nginx ждёт 60 секунд — если приложение не ответило, отдаёт 504
КодЧто происходит
502 Bad GatewayПрокси не смог установить связь с приложением (упало, не запущено, мусор в ответе)
504 Gateway TimeoutСвязь установлена, но приложение думает слишком долго

Самая частая причина. Запрос к БД работает 5+ минут вместо миллисекунд. Обычно:

  • Нет индекса на нужной колонке
  • Сложный JOIN на нескольких миллионах строк
  • Полный скан (Seq Scan) большой таблицы

2. Внешний API не отвечает

Section titled “2. Внешний API не отвечает”

Ваше приложение зовёт чужой API (платёжная система, CRM, сервис уведомлений), а тот висит. Приложение ждёт ответа — клиент видит 504.

В Python/Node.js приложении одна операция вошла в бесконечный цикл или ждёт mutex. Другие запросы не обрабатываются.

4. Heavy задача в синхронном HTTP

Section titled “4. Heavy задача в синхронном HTTP”

Кто-то решил отправить email или сгенерировать PDF прямо в HTTP-обработчике. Это занимает 30+ секунд → 504.

5. Долгий поиск/индексация

Section titled “5. Долгий поиск/индексация”

ElasticSearch, Sphinx и т.п. — если индекс не оптимизирован, запрос может работать минуты.

1. Лог nginx с указанием времени:

Terminal window
sudo tail -50 /var/log/nginx/error.log | grep -i timeout

Типичное сообщение:

upstream timed out (110: Connection timed out) while reading response header

2. Slow query log БД:

PostgreSQL:

Terminal window
sudo tail -100 /var/log/postgresql/postgresql-16-main.log | grep duration

MySQL:

Terminal window
sudo tail -100 /var/log/mysql/slow.log

Если видите запросы дольше 1 секунды — вот они.

3. APM (если есть)

Sentry, NewRelic, Datadog — покажут какие именно эндпоинты медленные. Без APM — придётся профилировать вручную.

4. Лог приложения с timing:

Хороший фреймворк (Django, Laravel, Rails) пишет время каждого запроса в лог:

[INFO] POST /api/orders/create completed in 47230ms

47 секунд — вот ваш 504. Эндпоинт /api/orders/create нужно чинить.

Сценарий A: медленный SQL

Добавить индекс на колонку которая используется в WHERE/JOIN:

CREATE INDEX idx_orders_user_id ON orders(user_id);

Использовать EXPLAIN для анализа плана запроса:

EXPLAIN ANALYZE SELECT ... ;

Если видите Seq Scan на большой таблице — нужен индекс.

Сценарий B: внешний API

Поставьте таймаут на внешние HTTP-запросы:

# Python requests
response = requests.get(url, timeout=5)
# Python httpx
async with httpx.AsyncClient(timeout=5) as client:
response = await client.get(url)

Если API не отвечает за 5 секунд — лучше показать пользователю ошибку, чем висеть 60 секунд.

Сценарий C: heavy задача в HTTP-обработчике

Вынесите в фоновый воркер. Celery, RabbitMQ, простая очередь в БД. Принцип:

  1. Принять запрос
  2. Поставить задачу в очередь
  3. Сразу вернуть 202 Accepted с ID задачи
  4. Клиент опрашивает статус по /api/tasks/{id}

Сценарий D: увеличить timeout как костыль

В крайнем случае:

proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;

Но это не решение, а его маскировка. Запросы в 5 минут для веба — это плохой UX, надо чинить причину.

Если сайт за Cloudflare/CDN и видите 504 от него — может быть два варианта:

  1. Ваш origin сервер реально медленный — Cloudflare ждёт ответа дольше своего таймаута (по умолчанию 100 секунд)
  2. Origin недоступен — Cloudflare попробовал подключиться, не смог

Проверьте напрямую: curl -I https://your-server-ip-or-direct-domain. Если медленно и без Cloudflare — чините origin.

Если вы видите 504 на своём сайте:

  1. Подождите 2-3 минуты — возможно, разовая нагрузка
  2. Свяжитесь с хостером — у них может быть проблема
  3. Свяжитесь с разработчиком — нужны логи, профилирование
  4. Подключите мониторинг — увидеть повторяется ли проблема

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

Monisite:

  • Каждую минуту проверяет ваш сайт с таймаутом 15 секунд
  • Если сайт отвечает дольше — это уже DOWN, вы получаете алерт
  • Видите на каких URL чаще таймауты — где именно медленный код

Подключить мониторинг →