Буферизация в Nginx: что ревьюить в конфигурации
Буферизация Nginx может защитить приложение от медленных клиентов, но при неудачных настройках начинает грузить RAM и диск. Разбираем, какие директивы проверять, где искать скрытые задержки и как измерять эффект.

Сервис может отдавать быстрый ответ приложению, но держать соединение с медленным клиентом ещё десятки секунд. В этот момент буферизация Nginx либо изолирует upstream от клиента, либо превращается в источник расхода памяти, временных файлов и задержек. На ревью конфигурации Nginx Open Source 1.24–1.27 важно проверять не отдельные числа, а весь путь ответа: размер данных, скорость клиента, лимиты worker-процесса и поведение диска.
Сначала определите, что именно буферизуется
В Nginx есть два разных сценария. proxy_buffering управляет буферизацией ответа от upstream. proxy_request_buffering — чтением тела запроса клиента перед отправкой его в upstream. Эти настройки часто смешивают, хотя риски у них разные.
- Ответ: приложение может быстро сформировать данные, а Nginx будет постепенно отдавать их медленному клиенту.
- Запрос: Nginx сначала принимает тело от клиента, а затем передаёт его приложению. Это влияет на загрузки, таймауты и возможность ретрансляции запроса.
- Временный файл: если ответ не помещается в память, Nginx может записать его во временный файл. Тогда узким местом становится не только RAM, но и диск.
На ревью сначала составьте карту endpoint’ов. Ответ JSON на несколько килобайт, выгрузка на сотни мегабайт и поток событий не должны автоматически получать одну и ту же политику.
Термин: upstream — сервер или группа серверов, куда Nginx передаёт запрос. Обычно это приложение, API-шлюз или другой прокси.
Главный вопрос: кого защищает буферизация
При включённой буферизации Nginx читает ответ upstream в буферы и освобождает приложение от необходимости держать соединение с медленным клиентом. Это полезно для обычных коротких HTTP-ответов: приложение быстрее освобождает worker, а клиент получает данные в своём темпе.
Цена — память на соединение и возможность записи ответа во временный файл. Если одновременно открыто много соединений, даже умеренный объём буферов умножается на их количество. Поэтому фраза «буферы маленькие» без оценки конкурентности ничего не говорит о расходе памяти.
При выключенной буферизации Nginx передаёт ответ клиенту по мере чтения из upstream. Такой режим может быть уместен для Server-Sent Events, потоковой генерации и некоторых длинных ответов. Но медленный клиент тогда дольше удерживает соединение с приложением, а приложение дольше занято обслуживанием этого запроса.
Буферизация — не ускоритель ответа. Это механизм разделения скоростей upstream и клиента, который обменивает память и диск на более короткую занятость приложения.
Что проверять в конфигурации
1. Не ограничивайтесь строкой proxy_buffering
В ревью нужно смотреть связку директив: proxy_buffering, proxy_buffer_size, proxy_buffers, proxy_busy_buffers_size, proxy_max_temp_file_size и proxy_temp_file_write_size. Их смысл связан: первые параметры задают память, следующие определяют, может ли ответ уйти на диск и какими порциями он туда записывается.
Не подставляйте в комментарий «нормальные» значения без измерений. Размер страницы памяти и значения по умолчанию зависят от версии, платформы и сборки. На ревью зафиксируйте фактическую конфигурацию команды nginx -T, включая унаследованные настройки из http и server.
2. Проверьте размер первого буфера
proxy_buffer_size используется для первой части ответа, в том числе заголовков. Слишком маленькое значение проявляется не как медленная отдача, а как ошибка при чтении заголовков upstream. В логах можно увидеть сообщения вроде upstream sent too big header while reading response header from upstream.
Особенно внимательно смотрите endpoint’ы с крупными cookie, большим числом заголовков авторизации, длинными redirect-адресами и сложными служебными заголовками. Увеличивать буфер на весь Nginx из-за одного endpoint’а обычно хуже, чем локализовать настройку.
3. Посчитайте память на соединение
proxy_buffers задаёт количество и размер буферов для ответа. В ревью полезно считать не одно значение, а верхнюю оценку: буферы одного запроса умножаются на число одновременно буферизуемых соединений, а затем — на число worker-процессов с учётом прочих потребителей памяти.
Это не точный прогноз RSS: Nginx и ОС имеют дополнительные расходы, часть буферов выделяется по мере необходимости, а разные ветки конфигурации могут использовать разные параметры. Но такая оценка быстро показывает опасные места. Конфигурация, рассчитанная на 100 соединений, не становится безопасной при 10 000 только потому, что каждый буфер меньше мегабайта.
4. Ищите неявную запись на диск
Если ответ не помещается в заданные буферы, Nginx может использовать временный файл. На ревью проверьте каталог временных файлов, свободное место, тип диска, лимиты контейнера и наличие отдельного раздела. Нельзя считать запись на диск бесплатной: она создаёт I/O, конкурирует с логами и может закончиться исчерпанием ephemeral storage в контейнере.
proxy_max_temp_file_size 0 запрещает запись проксируемого ответа во временный файл. Это не универсальная оптимизация: большой ответ тогда должен обслуживаться в рамках доступной буферизации, а поведение нужно проверить на реальном размере ответа и скорости клиента.
Сравнение решений
| Режим | Что выигрываем | Чем платим | Что проверять на ревью |
|---|---|---|---|
| Буферизация включена | Upstream быстрее освобождается от медленного клиента | Память на соединение, возможный временный файл | Конкурентность, размеры ответа, RAM и диск |
| Буферизация выключена | Потоковая передача с меньшей задержкой до клиента | Медленный клиент дольше занимает приложение | Длительность соединений, worker’ы upstream, таймауты |
| Буферизация включена, запись на диск ограничена | Меньше неконтролируемого I/O | Крупные ответы могут упереться в память или ограничения ответа | Максимальный размер ответа и сценарии деградации |
Как ревьюить разные типы endpoint’ов
Обычный API
Для коротких JSON-ответов обычно проверяют, что буферизация не отключена без причины, а размер заголовков соответствует реальному трафику. Замечание должно ссылаться не на стиль, а на риск: например, «выключение буферизации удерживает соединение приложения при медленном клиенте; покажите метрики длительности upstream-соединений».
Выгрузки и большие файлы
Для выгрузок сначала выясните, где формируется файл. Если приложение генерирует ответ на лету, буферизация может создать большой временный файл на прокси. Если файл уже лежит в объектном хранилище или на файловом сервере, архитектура может быть лучше с прямой выдачей или отдельным location. Это уже вопрос маршрута данных, а не только размера proxy_buffers.
Потоки событий
Для SSE и похожих потоков важна доставка небольших фрагментов без ожидания заполнения буфера. Проверяйте отключение буферизации, заголовки ответа и таймауты. WebSocket — отдельный сценарий: кроме буферизации, ему нужна корректная передача Upgrade-заголовков и версия HTTP-прокси. Не объединяйте эти проверки в одно правило.
Загрузка файлов
Для запросов смотрите proxy_request_buffering, лимит размера тела и таймауты чтения. Если Nginx сначала полностью принимает файл, приложение может не видеть его до завершения загрузки. Если передача идёт потоково, upstream получает данные раньше, но сложнее становятся отмена, повторная отправка и обработка частично принятого тела.
Какие метрики нужны до изменения настроек
Без замеров изменение размера буферов превращается в угадайку. В access log полезно разделить время запроса и время ответа upstream: например, сравнивать $request_time и $upstream_response_time. Добавьте статус, размер ответа и признаки исчерпания диска. Для проблем с заголовками смотрите error log, а не только среднюю задержку API.
- Если
$upstream_response_timeмало, а$request_timeзаметно больше, ищите медленного клиента, передачу ответа или очередь на прокси. - Если растёт время upstream, отключение буферизации может удерживать соединения приложения дольше ожидаемого.
- Если задержки совпадают с I/O, проверяйте временные файлы, контейнерное хранилище и конкуренцию с логированием.
- Для потоков измеряйте время до первого байта и интервалы между фрагментами, а не только полное время запроса.
Сравнивайте минимум три режима нагрузки: быстрый клиент, ограниченный по скорости клиент и несколько параллельных больших ответов. Точные пороги зависят от размера ответа, числа worker’ов, лимитов контейнера и характеристик диска, поэтому переносить цифры из чужого стенда нельзя.
Что ломается первым
- Большие заголовки: появляется ошибка о слишком большом заголовке upstream. Проверяйте первый буфер и источник крупных cookie.
- Заполненный временный диск: новые запросы начинают ошибаться или резко замедляются. Проверяйте каталог, квоту и очистку временных файлов.
- Память при всплеске трафика: средняя нагрузка выглядит нормально, но параллельные большие ответы вызывают рост RSS и OOM. Нужен тест на пиковую конкурентность.
- Зависшие потоковые запросы: клиент или прокси не получает данные вовремя. Проверяйте буферизацию по всей цепочке, включая CDN и ingress.
- Разные location ведут себя по-разному: директива могла быть переопределена на другом уровне конфигурации. Всегда ревьюьте итоговый вывод
nginx -T.
Как оформить замечание на ревью
Хорошее замечание связывает директиву, сценарий и измеримый риск. Вместо «буферы настроены неправильно» пишите: «Для endpoint’а с потоковым ответом включена буферизация; покажите время до первого байта и интервалы доставки, либо обоснуйте, зачем ответ должен накапливаться». Для большой выгрузки: «Укажите максимальный размер ответа, лимит временного диска и поведение при его заполнении».
Отдельно просите владельца конфигурации назвать критерий успеха: меньшее время занятости upstream, отсутствие записи на диск, стабильный RSS или доставка первого события без задержки. Один универсальный порог для всех endpoint’ов здесь не работает.
Что делать дальше
Соберите итоговую конфигурацию через nginx -T, классифицируйте location по типу ответа и снимите базовые метрики до изменения. Затем протестируйте быстрый и медленный клиент на стенде, отдельно наблюдая RAM, I/O, время upstream и ошибки error log. После выката поставьте алерты на заполнение временного хранилища, рост длительных соединений и ошибки чтения ответа от upstream. Инвалидация кеша и настройка CDN — отдельные темы: здесь важно сначала доказать, что узкое место действительно находится в буферизации Nginx.
Аудитор договоров: Word/PDF договоры: скрытые штрафы и пени, протокол разногласий.
Спросить за 20 ₽Источники: NGINX documentation: ngx_http_proxy_module, NGINX documentation: ngx_http_log_module
Частые вопросы
Нужно ли всегда выключать proxy_buffering для быстрых ответов?
Почему Nginx пишет ответ во временный файл, хотя буферы настроены?
Что делать с ошибкой upstream sent too big header?
Чем опасно отключение proxy_request_buffering при загрузке файла?
Как понять, что проблема именно в буферизации, а не в приложении?
Подойдут ли эти рекомендации для другой версии Nginx?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.