Новинка Виртуальный VDS сервер в Нидерландах от 390р
Выберите продукт

Таймауты HTTP в Nginx без сюрпризов: client_body_timeout, proxy_read_timeout и друзья

Таймауты в Nginx — не «магические числа». От них зависят скорость сайта, доля 5xx/4xx в логах и стабильность апстримов. Разложим по полочкам client_body_timeout, proxy_read_timeout, keepalive и родственные директивы, покажем типовые профили и приёмы диагностики.
Таймауты HTTP в Nginx без сюрпризов: client_body_timeout, proxy_read_timeout и друзья

Если в логах периодически всплывают 504 Gateway Time-out, 408 Request Timeout или 499 Client Closed Request, почти всегда дело в некорректных таймаутах. В Nginx их много: одни отвечают за чтение запроса от клиента, другие — за общение с апстримом, третьи — за отправку ответа обратно в браузер. В этой статье я разберу ключевые директивы, покажу безопасные базовые значения и типовые профили для API, загрузок файлов, long‑polling и «медленных клиентов».

Зачем вообще трогать таймауты

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

Правило хорошего тона: глобально задаём умеренные значения, а для специфичных локаций (API, загрузки, стриминг) — адресно переопределяем.

Классы таймаутов в Nginx

Условно разделим на три группы: клиентские (читаем у клиента и отправляем клиенту), таймауты к апстриму (proxy/fastcgi/uwsgi/scgi/grpc) и keepalive‑параметры.

Клиентские

client_header_timeout — ожидаем заголовки запроса от клиента. Если клиент не прислал их вовремя, Nginx вернёт 408. Для обычных сайтов 10–15s достаточно; для мобайла за медленной сетью можно 20–30s.

client_body_timeout — интервал между двумя пакетами тела запроса. Критично для загрузок файлов и POST/PUT. Если пользователь грузит медленно и «замолкает» дольше таймаута — 408. Баланс: 30–60s обычно, при больших загрузках 120–300s.

send_timeout — не общее время ответа, а таймаут неактивности при отправке в сокет клиента. То есть если Nginx не смог записать очередную часть ответа в течение заданного времени (клиент очень медленный) — соединение закрывается. Типично 10–20s. Важно: это не ограничение общей длительности ответа.

Прокси к апстриму

proxy_connect_timeout — время на установку TCP‑соединения с апстримом. Сетевой сбой, SYN/ACK не пришёл — по истечении будет 504. Обычно 3–5s, если апстрим локальный — можно 1–2s.

proxy_send_timeout — таймаут неактивности при отправке запроса апстриму (интервалы записей). Важен при больших телах запросов и медленном апстриме. Обычно 30s; для больших upload‑прокси — до 300s.

proxy_read_timeout — таймаут неактивности чтения ответа от апстрима (интервалы чтений). Главный виновник 504 при долгих вычислениях или стриминге. Для обычного HTML/API 30–60s, для long‑polling/SSE/WebSocket‑апгрейда — минуты и даже часы.

Аналоги для других протоколов: fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout, и т. д.

Keepalive

keepalive_timeout — сколько держать HTTP‑соединение с клиентом в режиме keep‑alive после ответа. Часто 65s как разумный дефолт. Второй параметр, если задан, управляет значением в заголовке Keep-Alive: timeout=.... Можно задавать как keepalive_timeout 65s 20s;.

keepalive_requests — сколько запросов разрешить по одному соединению. Значения 100–1000 нормальны, в зависимости от трафика и поведения клиентов.

keepalive_time — общий лимит жизни keep‑alive‑соединения. Помогает не держать очень старые коннекты бесконечно.

Для апстрима (пул коннектов): upstream { keepalive ...; keepalive_timeout ...; keepalive_requests ...; }. Это снимает накладные расходы на частые TCP‑connect к бэкенду.

Визуальная схема потоков: клиент — Nginx — апстрим и точки срабатывания таймаутов

Базовые безопасные значения

Ниже стартовые пресеты для типичных сайтов. Это не догма; корректируйте под реальные задержки и профиль нагрузки.

# http {} или включаемый конфиг с дефолтами
client_header_timeout 15s;
client_body_timeout 30s;
send_timeout 15s;
keepalive_timeout 65s;
keepalive_requests 1000;
keepalive_time 2m;

# прокси по умолчанию
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffering on;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;

Что это даёт: быстрый фэйл при недоступности апстрима, терпимость к кратковременным паузам при приёме тела запроса и адекватные ожидания ответа.

Профили под задачи

1) Обычный сайт/лендинг/блог

Короткий TTFB и статический контент, редкие POST‑формы. Близко к «Базовым значениям». Можно даже чуть короче proxy_read_timeout — 15–20s, если всё отдаётся быстро и апстрим рядом. Для ускорения perceived‑скорости можно рассмотреть HTTP 103 Early Hints.

2) REST API с нестабильными апстримами

API нередко общается с внешними сервисами. Здесь лучше минимизировать «зависания» и быстрее отдавать ошибку на ретрай клиента или на очереди задач.

location /api/ {
    proxy_connect_timeout 3s;
    proxy_send_timeout 15s;
    proxy_read_timeout 20s;
    send_timeout 10s;
    # По месту можно включить circuit-breaker логикой proxy_next_upstream
}

Идея в том, чтобы не блокировать воркеры Nginx минутами, если апстрим «тупит». Лучше краткий таймаут и повторная попытка на клиенте или через брокер задач.

3) Большие загрузки файлов

Тут важны два направления: входящий трафик от клиента и исходящий в апстрим (если проксируем upload до бэкенда). Ошибка в типовых настройках — оставить client_body_timeout и proxy_send_timeout слишком короткими.

location /upload/ {
    client_max_body_size 2g;
    client_body_timeout 5m;

    proxy_request_buffering off;  # Стримим в апстрим, без буфера на диск
    proxy_send_timeout 5m;        # Пишем долго в бэкенд
    proxy_read_timeout 2m;        # Ждём ответ бэкенда
}

Если клиенты могут быть «медленными», не забывайте про send_timeout на отдаче ответа и возможное ограничение скорости limit_rate, чтобы не убить канал. При отдаче больших файлов посмотрите материал про HTTP Range и кеширование статики.

4) Long‑polling, SSE и «тихие» стримы

Здесь proxy_read_timeout должен быть большим, иначе Nginx оборвёт соединение в момент, когда бэкенд специально «молчит», удерживая канал открытым.

location /events/ {
    proxy_read_timeout 1h;  # длительная тишина между событиями — это нормально
    proxy_send_timeout 1m;
    # Для SSE добавляют буферы и заголовки, но ключевой параметр — именно proxy_read_timeout
}

Если используете WebSocket‑апгрейд, обычно тоже поднимают proxy_read_timeout до 1h и выше.

Как «читаются» таймауты и что за коды ошибок

Важно понимать, какие коды вернёт Nginx при срабатывании разных таймаутов, и кто виновник.

  • 408 Request Timeout — клиент не прислал заголовки/тело вовремя (client_header_timeout, client_body_timeout).
  • 504 Gateway Time-out — апстрим не ответил вовремя (proxy_connect_timeout, proxy_read_timeout, реже proxy_send_timeout).
  • 499 Client Closed Request — клиент сам закрыл соединение до окончания ответа. Часто результат нетерпеливого браузера или ретраев.
  • 502 Bad Gateway — апстрим оборвал соединение или прислал некорректный ответ (не таймаут).

Ещё два важных момента:

  • send_timeout — это таймаут неактивности записи в клиента, а не «максимальная длительность ответа». Ограничивайте длительность ответов другими способами или продуманной архитектурой.
  • Таймауты — интервальные. Например, proxy_read_timeout 30s означает «между двумя чтениями от апстрима должно пройти не больше 30s», а не «весь ответ должен уложиться в 30s».

Диагностика: лог‑форматы и метрики

Хороший log_format экономит часы на поиске первопричины. Добавьте в access‑лог поля времен апстрима и общего времени запроса.

log_format timed '$remote_addr $request $status '
                 '$request_time $upstream_connect_time '
                 '$upstream_header_time $upstream_response_time';
access_log /var/log/nginx/access_timed.log timed;

$request_time покажет, сколько занимал весь цикл. $upstream_connect_time годится для ловли проблем DNS/сети/handshake к бэкендам. $upstream_response_time — сколько апстрим «думал» или «стримил». Сопоставляйте с кодами 408/499/504 и поймёте, где зажим.

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

Метрики Nginx: request_time и upstream_response_time на панели мониторинга

Подводные камни и антипаттерны

  • «0» как отключение. У send_timeout значение 0 отключит таймаут вовсе — почти всегда плохая идея. Долгие медленные клиенты будут держать воркеры.
  • Одинаковые таймауты для всего. Загрузки, API и стриминг живут по разным правилам. Делайте разные локации и профили.
  • Большие таймауты вместо очередей. Если апстрим реально работает минутами — не лечится таймаутом. Перестройте поток: приём задачи, 202 Accepted, прогресс в фоне, опрос или callback.
  • buffering off без нужды. proxy_request_buffering off и proxy_buffering off усиливают зависимость от скорости клиента/апстрима и увеличивают количество «медленных» коннектов. Включайте осознанно.
  • Забытый upstream keepalive. Частые короткие запросы к бэкенду без пула коннектов — это лишние SYN/ACK и нагрузка. Настройте keepalive в upstream.
  • Нет защиты от тайм‑аутов на отправке. Комбинируйте send_timeout с ограничением скорости (limit_rate) и разумными буферами, чтобы не держать гигабайтные очереди на клиентов с узким каналом.

Практический чек‑лист настройки

  1. Опишите профиль трафика: доля статического, API, загрузок, стриминга. Разведите это по локациям.
  2. Задайте умеренные глобальные дефолты: 15–30s для чтения/отправки, 65s для keep‑alive.
  3. Для upload‑роутов увеличьте client_body_timeout и proxy_send_timeout, подумайте о proxy_request_buffering off.
  4. Для long‑polling/SSE/WebSocket поднимите proxy_read_timeout до минут/часов.
  5. Для REST API к сторонним сервисам сократите proxy_connect_timeout и proxy_read_timeout, чтобы быстрее отдавать ошибку.
  6. Включите расширенный access‑лог с временами апстрима и начинайте наблюдать за реальными распределениями.
  7. Проверьте upstream‑keepalive и лимиты keepalive_requests/keepalive_time для клиентов.
  8. Рассмотрите reset_timedout_connection on, если хотите немедленно освобождать ресурсы при тайм‑аутах клиента.

Набор примеров конфигурации

http {
    client_header_timeout 15s;
    client_body_timeout 30s;
    send_timeout 15s;
    keepalive_timeout 65s 20s;
    keepalive_requests 1000;
    keepalive_time 2m;

    upstream app_backend {
        server 127.0.0.1:9000;
        keepalive 64;
        keepalive_timeout 60s;
        keepalive_requests 1000;
    }

    server {
        listen 80;
        server_name example.test;

        # Быстрый статика‑роут
        location /static/ {
            root /var/www/site;
            expires 30d;
        }

        # API с осторожными таймаутами
        location /api/ {
            proxy_pass http://app_backend;
            proxy_connect_timeout 3s;
            proxy_send_timeout 15s;
            proxy_read_timeout 20s;
            proxy_buffering on;
        }

        # Загрузки
        location /upload/ {
            client_max_body_size 2g;
            client_body_timeout 5m;

            proxy_pass http://app_backend;
            proxy_request_buffering off;
            proxy_send_timeout 5m;
            proxy_read_timeout 2m;
        }

        # Long‑polling/SSE
        location /events/ {
            proxy_pass http://app_backend;
            proxy_buffering off;
            proxy_read_timeout 1h;
            proxy_send_timeout 1m;
        }
    }
}

Полный контроль над конфигурацией Nginx типично доступен на VDS. На шаред‑площадках права ограничены, что усложняет тонкую настройку таймаутов и пулов соединений.

FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды

HTTP/2 и нюансы

Для HTTP/2 есть дополнительные параметры: http2_idle_timeout и http2_recv_timeout. Первый лимитирует простои, второй — чтение данных. Если у вас много долгоживущих соединений (SSE/графики), проверьте эти значения, чтобы не убить полезные стримы.

Связанные параметры, которые часто путают с таймаутами

  • client_max_body_size — ограничение размера загрузок, не таймаут.
  • proxy_buffers и proxy_busy_buffers_size — буферизация ответа апстрима; влияет на поведение при медленных клиентах, но не задаёт время.
  • limit_rate и limit_rate_after — ограничение скорости отдачи; косвенно влияет на send_timeout, но это не таймауты.

Методика подбора значений

Начните с разумных дефолтов и включите метрики/логи. Снимите распределение $upstream_response_time и $request_time по перцентилям. Если 95‑й перцентиль API укладывается в 600ms, нет смысла держать proxy_read_timeout в 300s — сократите до 10–20s. Для upload‑роутов измерьте фактическое время заливки на «медленном» канале и умножьте на коэффициент запаса 2–3.

Не пытайтесь одной цифрой решить архитектурные проблемы. Если ответ бэкенда может готовиться минуты, уводите работу в фон, а клиенту отдавайте быстрый квиток и статус‑эндпоинт. Таймауты должны спасать от зависаний, а не прикрывать медленный дизайн.

Итоги

Таймауты в Nginx — это набор рычагов, управляющих тем, сколько мы готовы ждать клиента и апстрим. Осознанный выбор client_body_timeout, proxy_read_timeout, send_timeout и друзей избавляет от 504/408/499, снижает нагрузку и делает систему предсказуемой. Держите умеренные дефолты, настройте адресные профили под сценарии трафика и опирайтесь на логи и перцентили — и сюрпризов станет в разы меньше.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...