ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

HTTP‑лимиты в Nginx: client_max_body_size и тело запроса для PHP и API

Почему Nginx внезапно отвечает 413, 400 или зависает на загрузке файлов? Часто причина в лимитах тела HTTP‑запроса: client_max_body_size, client_body_buffer_size, client_body_timeout и директивы PHP. Разберём, как уровни взаимодействуют, где задавать лимиты и какие пресеты подходят для сайтов, API и инфраструктуры на VDS.
HTTP‑лимиты в Nginx: client_max_body_size и тело запроса для PHP и API

Ошибки загрузки файлов в веб‑приложениях почти всегда упираются в лимиты: где‑то в стеке «браузер → Nginx → PHP» стоит ограничение на размер или время приёма тела HTTP‑запроса.

Чаще всего админы сталкиваются с кодами 413 Request Entity Too Large, 400 Bad Request или странными подвисаниями при загрузке «тяжёлых» файлов. В логах всплывают параметры Nginx client_max_body_size, client_body_buffer_size, client_body_timeout, а рядом — знакомые PHP‑директивы upload_max_filesize и post_max_size.

В этой статье разберём, как именно Nginx обрабатывает тело HTTP‑запроса, как работают ключевые директивы client_* для тела запроса, как они взаимодействуют с PHP/FastCGI, и предложим готовые пресеты для типичных задач: загрузка файлов, REST/GraphQL API, микросервисы на VDS.

Как Nginx принимает тело HTTP‑запроса

Nginx выступает фронтендом: он принимает HTTP‑запрос от клиента, частично или полностью буферизует тело, а затем проксирует его дальше — в PHP‑FPM или бэкенд‑API. Понимание этой цепочки важно, потому что лимиты могут сработать на каждом из уровней отдельно.

Общая схема выглядит так:

  • Клиент открывает HTTP(S)‑соединение и начинает отправлять заголовки.
  • Nginx читает заголовки, применяет к ним свои лимиты (не тема этой статьи).
  • После заголовков Nginx начинает принимать тело запроса (файл, форму, JSON и т. д.).
  • На этапе чтения тела работают директивы: client_max_body_size, client_body_buffer_size, client_body_timeout и настройки временных директорий.
  • Когда тело принято (целиком или частично в буфер), Nginx, как правило, делает proxy_pass или fastcgi_pass дальше в приложение.

Если запрос нарушает лимит по размеру или времени, Nginx завершает обработку и отправляет ошибку (обычно 413 или 408/400). До PHP/бэкенда такая заявка даже не доходит.

client_max_body_size: главный лимит размера тела

Директива client_max_body_size — это максимальный размер тела HTTP‑запроса, который Nginx вообще готов принять от клиента. Она применяется на уровне http/server/location и наследуется вниз.

http {
    client_max_body_size 10m;

    server {
        # для этого сервера лимит 50 MB
        client_max_body_size 50m;

        location /upload/ {
            # а тут, для загрузок, лимит 200 MB
            client_max_body_size 200m;
        }
    }
}

Ключевые моменты:

  • Ограничение работает ещё до PHP/бэкенда. Если пользователь шлёт файл на 300 MB при лимите 100 MB, то PHP этот запрос не увидит вообще.
  • Значение по умолчанию в большинстве сборок Nginx — 1m. На многих серверах админы забывают его поднять.
  • Можно задать 0 — означает отсутствие лимита на стороне Nginx (но это редко разумно в проде).

Важно: client_max_body_size проверяется по заголовку Content-Length (если есть) и по фактически прочитанным данным. Nginx может оборвать соединение, как только поймёт, что лимит превышен.

Типичные симптомы превышения client_max_body_size

  • Браузер показывает страницу с ошибкой или короткий ответ сервера 413 (Request Entity Too Large).
  • В error.log Nginx появляются записи вида: client intended to send too large body.
  • В приложении (PHP/Node.js и т. д.) нет никаких логов по этому запросу — он даже не дошёл до бэкенда.

Где задавать client_max_body_size: http/server/location

Рекомендуемая практика:

  • На уровне http оставить относительно небольшой «глобальный» лимит, например: client_max_body_size 10m;.
  • Для конкретных виртуальных хостов (server) поднимать лимит, если там реально нужны крупные запросы.
  • Для «точек загрузки» (location /upload, /api/upload и т. п.) задавать максимально допустимые значения — именно там, где вы ждёте большие тела.

Такой подход помогает не допустить случайной загрузки гигантских файлов на все эндпоинты (например, API без необходимости).

Схема обработки тела HTTP‑запроса в Nginx с буферами и временными файлами

client_body_buffer_size: буфер тела запроса в памяти

После того как Nginx принял решение тело запроса не отклонять, он должен где‑то его сохранить при чтении. Для этого используется внутренняя схема буферизации: часть тела — в памяти, остальное может быть сброшено во временные файлы.

За размер буфера в памяти отвечает директива client_body_buffer_size. Она определяет, сколько байт (или килобайт/мегабайт) Nginx может держать в памяти до того, как начнёт использовать временные файлы на диск.

server {
    client_max_body_size 50m;
    client_body_buffer_size 512k;
}

Если тело запроса:

  • меньше или равно client_body_buffer_size — всё помещается в память;
  • больше — Nginx создаёт временный файл в директории client_body_temp_path (или дефолтной) и записывает туда остальное.

Это влияет сразу на две вещи:

  • Потребление RAM при большом количестве одновременных запросов с телом (например, массовые POST/PUT в API).
  • Нагрузку на диск из‑за временных файлов, особенно на HDD или загруженных SSD.

Как подбирать client_body_buffer_size

Основные ориентиры:

  • Для «обычных» POST‑форм (пара килобайт) достаточно 8–32k.
  • Для REST/JSON API, где payload может быть 50–200 KB, разумно 128–512k.
  • Для загрузки файлов сам размер файла в RAM хранить не нужно — пусть тело уходит во временный файл, поэтому сильно поднимать буфер нет смысла (обычно 256–512k достаточно).

Слишком большой client_body_buffer_size при большом количестве одновременных запросов может привести к избыточному потреблению памяти. Слишком маленький — к лишним операциям записи/чтения на диск, но в большинстве случаев это меньшая проблема.

client_body_timeout: сколько Nginx ждёт тело запроса

client_body_timeout определяет, сколько секунд Nginx готов ждать, пока клиент пришлёт следующую порцию данных тела запроса. То есть это не общий таймаут, а таймаут между чтениями.

server {
    client_body_timeout 30s;
}

Если клиент начал отправку, но затем долго «молчит» (например, плохой канал, зависший загрузчик, атака Slowloris), Nginx по истечении client_body_timeout разрывает соединение.

Практические рекомендации:

  • Для сайтов с обычными формами достаточно 10–30 секунд.
  • Для тяжёлых загрузок по медленным каналам (например, крупные видео) таймаут можно поднять до 60–120 секунд.
  • Ставить бесконечные значения не стоит: таймауты — один из инструментов защиты от медленных атак и зависших клиентов.

Помните, что client_body_timeout не равен «максимальному времени загрузки». Клиент может отправлять данные много минут подряд, если между порциями не превышается указанный интервал.

Другие важные директивы для тела запроса

Кроме основных трёх параметров есть ещё несколько, которые часто всплывают при работе с POST/PUT и загрузками.

client_body_temp_path: где хранятся временные файлы

Когда тело запроса не помещается в буфер, Nginx пишет его во временные файлы в директории client_body_temp_path (или в стандартную temp‑директорию, если путь не переопределён).

http {
    client_body_temp_path /var/nginx/body_temp 1 2;
}

Рекомендации:

  • Размещайте temp‑директорию на достаточно быстром и «живучем» диске.
  • Следите за правами и наличием места на разделе: переполненный temp‑раздел = массовые ошибки при загрузке.

large_client_header_buffers и прочие лимиты

Хотя они не относятся непосредственно к телу, на практике часто путаются с ним. Если в заголовках (например, очень длинные cookies) превышается large_client_header_buffers, Nginx тоже может отвечать 400/413, и в логах это выглядит схоже. Проверяйте сообщения в error.log, чтобы не лечить «не тот» лимит.

Взаимодействие Nginx‑лимитов с PHP (upload_max_filesize, post_max_size)

У большинства PHP‑проектов критичный кейс — загрузка файлов: аватары, документы, медиа. Тут одновременно работают:

  • Nginx‑лимит client_max_body_size;
  • PHP‑лимиты upload_max_filesize и post_max_size;
  • и иногда ограничения в приложении (например, максимальный размер файла в CMS).

Как эти лимиты складываются

Упрощённая логика:

  • Если размер файла > client_max_body_size — Nginx отдаёт 413, PHP не видит запрос.
  • Если размер файла <= client_max_body_size, но > upload_max_filesize — PHP отклонит загрузку: файл «обрежется», или появится ошибка уровня приложения (в зависимости от кода).
  • post_max_size ограничивает суммарный размер всего тела POST (файл + поля формы). Если его не хватает, PHP также отбрасывает часть данных или выдаёт ошибку.

Чтобы избежать путаницы, имеет смысл держать их в согласованном соотношении:

# Nginx (nginx.conf, server или location)
client_max_body_size 50m;

# PHP (php.ini или аналог)
upload_max_filesize = 32M
post_max_size = 40M

То есть:

  • client_max_body_size >= post_max_size >= upload_max_filesize.
  • Nginx ограничивает «абсолютный максимум».
  • PHP накладывает более точные правила на уровне приложения.

Типичные симптомы несогласованных лимитов

  • Пользователь получает 413 сразу после начала загрузки — не хватает client_max_body_size.
  • Загрузка завершается «успешно» на фронтенде, но файл в системе отсутствует или нулевого размера — PHP порезал из‑за upload_max_filesize или post_max_size.
  • В phpinfo() и конфиге Nginx — одно, а в реальности другое, потому что на бою используются разные php.ini или override в .user.ini/php_value.

Пресеты настроек для разных сценариев

Теперь соберём рекомендации во что‑то более прикладное. Примеры ниже — не догма, а отправная точка, которую стоит адаптировать под свой трафик и железо (особенно на VDS с ограниченным RAM и IO).

1. Классический PHP‑сайт с формами и небольшими файлами

Типичный блог, корпоративный сайт, интернет‑магазин без гигантского медиа‑контента.

http {
    client_max_body_size 10m;
    client_body_buffer_size 64k;
    client_body_timeout 20s;
}

server {
    # при необходимости можно чуть поднять только для этого хоста
}

PHP:

upload_max_filesize = 5M
post_max_size = 8M
max_execution_time = 60

Такой набор:

  • не даёт случайно заливать огромные файлы;
  • держит тело запроса в памяти (64 KB достаточно для большинства POST‑форм);
  • не вешает соединения при очень медленных или «странных» клиентах.

2. Загрузка фотографий и документов (до 50–200 MB)

Подходит для личных кабинетов, CRM, внутренних файловых хранилищ.

server {
    client_max_body_size 200m;
    client_body_buffer_size 256k;
    client_body_timeout 60s;

    location /upload/ {
        # можно переопределить, если на этом эндпоинте нужны другие лимиты
    }
}

PHP:

upload_max_filesize = 128M
post_max_size = 150M
max_execution_time = 300

Здесь client_max_body_size даёт небольшой запас над post_max_size, чтобы не упереться в Nginx при шапках и служебных данных, а client_body_timeout увеличен, чтобы держать медленных клиентов.

3. JSON/REST/GraphQL API на Nginx (PHP или другой бэкенд)

В API обычно тела запросов не гигантские, но запросов может быть много. Поэтому главный фокус — экономить RAM, не переливая всё в диск.

server {
    client_max_body_size 5m;
    client_body_buffer_size 128k;
    client_body_timeout 15s;
}

Эти значения:

  • не разрешают нетипично большие JSON‑тела (снижая риск DoS по объёму);
  • держат большинство payload целиком в памяти, что ускоряет бэкенд и снижает IO;
  • с достаточно жёстким client_body_timeout лучше защищают API от медленных атак.

Особенности на VDS: RAM, IO и планирование лимитов

Когда вы настраиваете Nginx на VDS, вопрос лимитов тела запроса становится особенно чувствительным. У вас ограниченные ресурсы RAM и диска (часто на одном и том же SSD с базой данных), и неправильные значения быстро приводят к деградации производительности.

На что смотреть:

  • Объём RAM. Умножайте предполагаемое максимальное число одновременных запросов с телом на client_body_buffer_size. Если получается заметная часть всей памяти — буфер завышен.
  • IO‑нагрузка на диск. Если client_body_buffer_size слишком мал, а запросов с крупными телами много, Nginx будет постоянно писать и читать временные файлы.
  • Тип нагрузки. Для API с маленькими payload выгоднее больше RAM и меньше дисковых операций; для редких больших загрузок допустимо опираться на диск.

Для типового VDS с 2–4 GB RAM можно ориентироваться на такие «безопасные» пресеты:

  • client_body_buffer_size 64–256k;
  • client_max_body_size до 50–200m (только на нужных локациях);
  • client_body_timeout 15–60s.

А для многопользовательских систем с большим потоком запросов стоит дополнительно ограничивать или шардинговать эндпоинты загрузки и мониторить IO по временным директориям Nginx.

Дашборд мониторинга VDS с графиками дискового IO и памяти при загрузке файлов

Диагностика: как понять, где именно упёрлись в лимит

Практический чек‑лист при проблемах с загрузкой файлов и POST‑запросами:

  1. Посмотреть error.log Nginx при воспроизведении проблемы.
    • Фразы client intended to send too large body почти всегда означают срабатывание client_max_body_size.
    • Сообщения о таймаутах чтения тела указывают на client_body_timeout.
  2. Проверить ответ сервера через curl -v.
    • Код 413 — почти наверняка client_max_body_size.
    • Код 408 или 400 на долгих загрузках — возможен client_body_timeout или лимит заголовков.
  3. Сравнить размер загружаемого файла с client_max_body_size, upload_max_filesize и post_max_size.
  4. Убедиться, что правите нужный конфиг и Nginx перезагружен (а не только перезапущен PHP‑FPM).
  5. Проверить временные директории Nginx и PHP: есть ли место на диске, корректные ли права.

Если вы параллельно настраиваете кэш или проксирование статики, может быть полезно почитать и про работу с HTTP‑коды диапазонов и кеширование в отдельном разборе: см. материал про настройки Range и кеш на Nginx и Apache по ссылке тонкая настройка Range и кеширования в Nginx и Apache.

Безопасность: лимиты как защита от DoS и багов клиента

Параметры client_max_body_size, client_body_buffer_size и client_body_timeout — это не только про удобство загрузки файлов. Это ещё и важные элементы безопасности:

  • Ограничение объёма тела запроса не даёт злоумышленнику легко выжечь вам весь диск или память массовой отправкой гигантских POST‑запросов.
  • Таймауты на чтение тела защищают от медленных атак, которые пытаются занять воркеры Nginx минимальным трафиком.
  • Разумный размер буфера в памяти помогает избежать ситуации, когда при пике запросов заканчивается RAM и система уходит в своп.

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

Итоги

Параметры client_max_body_size, client_body_buffer_size и client_body_timeout в Nginx напрямую определяют, какие HTTP‑запросы ваш сервер готов принимать, как именно они будут буферизоваться и сколько времени сервер будет терпеливо ждать тело запроса. Их нужно настраивать в связке с PHP‑лимитами (upload_max_filesize, post_max_size) и с учётом ресурсов вашей инфраструктуры — особенно на VDS, где любая ошибка в лимитах быстро выливается в переполненный диск или нехватку RAM.

Начните с консервативных значений, выровняйте их с реальными сценариями использования (типичные размеры файлов, размер JSON‑payload в API), затем по снимкам профиля нагрузки корректируйте буферы и таймауты. Регулярный анализ логов Nginx и мониторинг мест под временные файлы помогут заранее заметить, что пришло время пересмотреть настройки.

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

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

Лимиты ресурсов на VDS: ulimit, sysctl и настройка для веб‑проектов OpenAI Статья написана AI (GPT 5)

Лимиты ресурсов на VDS: ulimit, sysctl и настройка для веб‑проектов

На новом VDS всё обычно летает, пока сайт не вырастет и не упрётся в скрытые лимиты: открытые файлы, процессы, сокеты, память. Раз ...
PHP uploads: настройка загрузки файлов и медиа на Nginx и Apache OpenAI Статья написана AI (GPT 5)

PHP uploads: настройка загрузки файлов и медиа на Nginx и Apache

Разбираем, как в PHP устроена загрузка файлов: временные файлы, лимиты размера и времени, ключевые параметры в php.ini, влияние на ...
cron на виртуальном хостинге: как настроить и не сломать сайт OpenAI Статья написана AI (GPT 5)

cron на виртуальном хостинге: как настроить и не сломать сайт

Разбираемся, как грамотно настроить cron на виртуальном хостинге: от формата расписаний и особенностей запуска PHP-скриптов до воп ...