Ошибка 504 Gateway Timeout — что значит и как исправить
HTTP 504 Gateway Timeout — ошибка прокси-сервера. Nginx (или другой реверс-прокси) ждал ответа от приложения слишком долго и сдался. По смыслу очень близка к 502 Bad Gateway, но с одним важным отличием: при 504 приложение отвечает, но слишком медленно.
- 🚨 Сайт показывает «504 Gateway Timeout»
- 🔍 Причина — приложение слишком долго обрабатывает запрос
- 🛠️ Чинится оптимизацией приложения или увеличением timeout прокси
- ⏱️ По умолчанию nginx ждёт 60 секунд — если приложение не ответило, отдаёт 504
Чем 504 отличается от 502
Section titled “Чем 504 отличается от 502”| Код | Что происходит |
|---|---|
| 502 Bad Gateway | Прокси не смог установить связь с приложением (упало, не запущено, мусор в ответе) |
| 504 Gateway Timeout | Связь установлена, но приложение думает слишком долго |
Частые причины
Section titled “Частые причины”1. Медленный SQL-запрос
Section titled “1. Медленный SQL-запрос”Самая частая причина. Запрос к БД работает 5+ минут вместо миллисекунд. Обычно:
- Нет индекса на нужной колонке
- Сложный JOIN на нескольких миллионах строк
- Полный скан (Seq Scan) большой таблицы
2. Внешний API не отвечает
Section titled “2. Внешний API не отвечает”Ваше приложение зовёт чужой API (платёжная система, CRM, сервис уведомлений), а тот висит. Приложение ждёт ответа — клиент видит 504.
3. Зависший поток
Section titled “3. Зависший поток”В Python/Node.js приложении одна операция вошла в бесконечный цикл или ждёт mutex. Другие запросы не обрабатываются.
4. Heavy задача в синхронном HTTP
Section titled “4. Heavy задача в синхронном HTTP”Кто-то решил отправить email или сгенерировать PDF прямо в HTTP-обработчике. Это занимает 30+ секунд → 504.
5. Долгий поиск/индексация
Section titled “5. Долгий поиск/индексация”ElasticSearch, Sphinx и т.п. — если индекс не оптимизирован, запрос может работать минуты.
Как диагностировать
Section titled “Как диагностировать”1. Лог nginx с указанием времени:
sudo tail -50 /var/log/nginx/error.log | grep -i timeoutТипичное сообщение:
upstream timed out (110: Connection timed out) while reading response header2. Slow query log БД:
PostgreSQL:
sudo tail -100 /var/log/postgresql/postgresql-16-main.log | grep durationMySQL:
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 47230ms47 секунд — вот ваш 504. Эндпоинт /api/orders/create нужно чинить.
Как исправить
Section titled “Как исправить”Сценарий A: медленный SQL
Добавить индекс на колонку которая используется в WHERE/JOIN:
CREATE INDEX idx_orders_user_id ON orders(user_id);Использовать EXPLAIN для анализа плана запроса:
EXPLAIN ANALYZE SELECT ... ;Если видите Seq Scan на большой таблице — нужен индекс.
Сценарий B: внешний API
Поставьте таймаут на внешние HTTP-запросы:
# Python requestsresponse = requests.get(url, timeout=5)
# Python httpxasync with httpx.AsyncClient(timeout=5) as client: response = await client.get(url)Если API не отвечает за 5 секунд — лучше показать пользователю ошибку, чем висеть 60 секунд.
Сценарий C: heavy задача в HTTP-обработчике
Вынесите в фоновый воркер. Celery, RabbitMQ, простая очередь в БД. Принцип:
- Принять запрос
- Поставить задачу в очередь
- Сразу вернуть
202 Acceptedс ID задачи - Клиент опрашивает статус по
/api/tasks/{id}
Сценарий D: увеличить timeout как костыль
В крайнем случае:
proxy_read_timeout 300;proxy_connect_timeout 300;proxy_send_timeout 300;Но это не решение, а его маскировка. Запросы в 5 минут для веба — это плохой UX, надо чинить причину.
Если за CDN
Section titled “Если за CDN”Если сайт за Cloudflare/CDN и видите 504 от него — может быть два варианта:
- Ваш origin сервер реально медленный — Cloudflare ждёт ответа дольше своего таймаута (по умолчанию 100 секунд)
- Origin недоступен — Cloudflare попробовал подключиться, не смог
Проверьте напрямую: curl -I https://your-server-ip-or-direct-domain. Если медленно и без Cloudflare — чините origin.
Если не разработчик
Section titled “Если не разработчик”Если вы видите 504 на своём сайте:
- Подождите 2-3 минуты — возможно, разовая нагрузка
- Свяжитесь с хостером — у них может быть проблема
- Свяжитесь с разработчиком — нужны логи, профилирование
- Подключите мониторинг — увидеть повторяется ли проблема
Чем поможет Monisite
Section titled “Чем поможет Monisite”504 особенно опасна тем что не похожа на падение: страница вроде грузится, но висит. Пользователь ждёт 30 секунд и уходит. Без мониторинга такие случаи невидимы.
Monisite:
- Каждую минуту проверяет ваш сайт с таймаутом 15 секунд
- Если сайт отвечает дольше — это уже DOWN, вы получаете алерт
- Видите на каких URL чаще таймауты — где именно медленный код
Что дальше
Section titled “Что дальше”- 502 Bad Gateway — близкий «брат»
- Таймаут соединения — когда сервер вообще не отвечает
- 500 Internal Server Error