Nginx: высокое потребление памяти — причины и решение
Сервер упирается в память, и подозрение падает на веб-сервер: Nginx высокое потребление памяти. Здесь важно сразу оговориться — сам Nginx крайне экономен и редко бывает виновником напрямую. Чаще память съедает то, что он обслуживает: PHP-FPM, буферы, кэш или неверные настройки. Разберём, как отличить реальную проблему Nginx от чужой и снизить расход RAM.
Содержание
- Первое действие: посмотрите, кто реально ест память
- Причина 1: слишком много воркеров и соединений
- Причина 2: раздутые буферы прокси и FastCGI
- Причина 3: виноват PHP-FPM, а не Nginx
- Причина 4: кэш и утечки в стороннем ПО
- Как отличить проблему Nginx от нехватки ресурсов
- Профилактика: держим память под контролем
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Первое действие: посмотрите, кто реально ест память
Прежде чем крутить настройки, выясните, действительно ли память ест Nginx или его бэкенд. Отсортируйте процессы по потреблению памяти:
ps aux --sort=-%mem | head -n 15
Почти всегда вы увидите, что сами процессы nginx: worker занимают немного — единицы или десятки мегабайт каждый. А вот php-fpm или процессы приложения могут отъедать основную часть RAM. Это ключевой вывод: если память съедает PHP-FPM или приложение, лечить надо их, а не Nginx. Nginx как реверс-прокси и раздатчик статики по своей природе лёгок. Реальные случаи, когда виноват именно он, связаны с раздутыми буферами, кэшем или неадекватным числом воркеров — их и разберём ниже.
Причина 1: слишком много воркеров и соединений
Nginx запускает рабочие процессы (worker), и каждое соединение потребляет немного памяти. Проблема возникает, когда worker_processes и worker_connections заданы неоправданно большими: например, воркеров назначено намного больше числа ядер. Оптимально — привязать число воркеров к ядрам:
worker_processes auto;
events {
worker_connections 1024;
}
worker_processes auto сам подберёт число по количеству ядер — это разумный дефолт. Раздувать worker_connections до огромных значений «на всякий случай» не нужно: реальный расход зависит от активных соединений, а завышенные лимиты просто резервируют ресурсы впустую. После правки проверьте конфиг и перезагрузите Nginx. Для большинства сайтов дефолтные значения уже адекватны, и трогать их стоит осознанно, а не копируя чужие «оптимизации» из интернета.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под сайтыПричина 2: раздутые буферы прокси и FastCGI
Буферы Nginx выделяются под каждый запрос, и если задать их слишком большими, при высокой параллельности расход памяти умножается. Директивы вроде proxy_buffers, proxy_buffer_size, fastcgi_buffers, client_body_buffer_size, выставленные с большим запасом, при сотнях одновременных запросов дают ощутимый суммарный расход. Посмотрите текущие значения в конфиге и приведите их к разумным:
proxy_buffers 8 16k;
proxy_buffer_size 16k;
fastcgi_buffers 8 16k;
Смысл в том, чтобы буферы соответствовали реальному размеру ответов, а не были завышены «про запас». Слишком маленькие буферы, наоборот, заставят Nginx писать во временные файлы на диск, что тоже плохо — нужна золотая середина. Если вы не меняли эти директивы намеренно и не понимаете, зачем они большие, вернитесь к дефолтам: они рассчитаны на типовую нагрузку и редко бывают причиной проблем.
Причина 3: виноват PHP-FPM, а не Nginx
Самый частый реальный сценарий: память ест не Nginx, а пул PHP-FPM за ним. Каждый воркер PHP-FPM держит в памяти интерпретатор и загруженное приложение, и при большом pm.max_children суммарный расход легко достигает гигабайтов. Посмотрите, сколько памяти в среднем занимает один воркер, и рассчитайте лимит под доступную RAM:
ps --no-headers -o rss -C php-fpm8.2 | awk '{s+=Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под сайты
Причина 2: раздутые буферы прокси и FastCGI
Буферы Nginx выделяются под каждый запрос, и если задать их слишком большими, при высокой параллельности расход памяти умножается. Директивы вроде proxy_buffers, proxy_buffer_size, fastcgi_buffers, client_body_buffer_size, выставленные с большим запасом, при сотнях одновременных запросов дают ощутимый суммарный расход. Посмотрите текущие значения в конфиге и приведите их к разумным:
proxy_buffers 8 16k;
proxy_buffer_size 16k;
fastcgi_buffers 8 16k;
Смысл в том, чтобы буферы соответствовали реальному размеру ответов, а не были завышены «про запас». Слишком маленькие буферы, наоборот, заставят Nginx писать во временные файлы на диск, что тоже плохо — нужна золотая середина. Если вы не меняли эти директивы намеренно и не понимаете, зачем они большие, вернитесь к дефолтам: они рассчитаны на типовую нагрузку и редко бывают причиной проблем.
Причина 3: виноват PHP-FPM, а не Nginx
Самый частый реальный сценарий: память ест не Nginx, а пул PHP-FPM за ним. Каждый воркер PHP-FPM держит в памяти интерпретатор и загруженное приложение, и при большом pm.max_children суммарный расход легко достигает гигабайтов. Посмотрите, сколько памяти в среднем занимает один воркер, и рассчитайте лимит под доступную RAM:
ps --no-headers -o rss -C php-fpm8.2 | awk '{s+=$1} END {print s/1024 " MB total"}'
Если каждый воркер ест, скажем, 80 МБ, а pm.max_children стоит 50, то на пике PHP-FPM запросит около 4 ГБ — и упрётся в память. Решение — задать pm.max_children исходя из формулы «доступная память минус система, делённая на размер одного воркера», оптимизировать приложение, чтобы оно потребляло меньше, и включить OPcache. Это снимает нагрузку с памяти куда эффективнее, чем правка настроек Nginx, который тут ни при чём.
Причина 4: кэш и утечки в стороннем ПО
Если вы настроили кэширование прокси в Nginx (proxy_cache), помните, что зона кэша резервирует память под ключи, а сам кэш занимает диск. Огромная зона keys_zone или неверные лимиты могут раздувать расход. Проверьте настройки кэша и приведите их к реальным потребностям. Также память может утекать в стороннем ПО — приложении, интерпретаторе, модуле, — и внешне это выглядит как «сервер забит», хотя Nginx снова ни при чём.
Общий диагностический приём — наблюдать динамику: если память растёт постепенно и не освобождается, это похоже на утечку в приложении или бэкенде, и перезапуск соответствующего сервиса временно её вернёт. Если память забивается скачком под нагрузкой — дело в числе воркеров и буферов бэкенда на пике. Разделяйте эти сценарии, прежде чем что-то менять:
watch -n 5 free -m
Как отличить проблему Nginx от нехватки ресурсов
Иногда «высокое потребление памяти» — это просто честная нехватка RAM под ваш проект. Сайт вырос, трафик увеличился, а сервер остался прежним. Посмотрите общую картину: сколько памяти всего, сколько занято, есть ли активный своп.
free -m
Если система постоянно в свопе и почти вся память занята бэкендом на нормальной нагрузке — это не «проблема Nginx», а сигнал, что ресурсов сервера уже мало. Тогда правка буферов даст копейки, а реально поможет оптимизация приложения или увеличение памяти сервера. Честно оцените: вы боретесь с неверной настройкой или упёрлись в потолок VPS. От этого зависит, крутить конфиг или добавлять ресурсы.
Профилактика: держим память под контролем
Чтобы память не становилась сюрпризом, настройте мониторинг потребления по процессам — тогда вы сразу видите, кто растёт: Nginx, PHP-FPM или приложение. Держите worker_processes auto, не раздувайте буферы без причины, рассчитывайте pm.max_children под реальную память сервера и размер воркера, включайте OPcache для PHP. Эти меры дают стабильный и предсказуемый расход.
И закладывайте запас RAM под пиковую нагрузку: сервер, живущий на пределе памяти в обычный день, свалится в своп в час пик и начнёт тормозить всё сразу. Если проект вырос, увеличение памяти сервера часто дешевле и надёжнее, чем бесконечная микрооптимизация конфигов. Помните главное: Nginx редко бывает настоящим виновником — начинайте диагностику с вопроса «а кто на самом деле ест память», и вы сэкономите много времени.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под сайты} END {print s/1024 " MB total"}'
Если каждый воркер ест, скажем, 80 МБ, а pm.max_children стоит 50, то на пике PHP-FPM запросит около 4 ГБ — и упрётся в память. Решение — задать pm.max_children исходя из формулы «доступная память минус система, делённая на размер одного воркера», оптимизировать приложение, чтобы оно потребляло меньше, и включить OPcache. Это снимает нагрузку с памяти куда эффективнее, чем правка настроек Nginx, который тут ни при чём.
Причина 4: кэш и утечки в стороннем ПО
Если вы настроили кэширование прокси в Nginx (proxy_cache), помните, что зона кэша резервирует память под ключи, а сам кэш занимает диск. Огромная зона keys_zone или неверные лимиты могут раздувать расход. Проверьте настройки кэша и приведите их к реальным потребностям. Также память может утекать в стороннем ПО — приложении, интерпретаторе, модуле, — и внешне это выглядит как «сервер забит», хотя Nginx снова ни при чём.
Общий диагностический приём — наблюдать динамику: если память растёт постепенно и не освобождается, это похоже на утечку в приложении или бэкенде, и перезапуск соответствующего сервиса временно её вернёт. Если память забивается скачком под нагрузкой — дело в числе воркеров и буферов бэкенда на пике. Разделяйте эти сценарии, прежде чем что-то менять:
watch -n 5 free -m
Как отличить проблему Nginx от нехватки ресурсов
Иногда «высокое потребление памяти» — это просто честная нехватка RAM под ваш проект. Сайт вырос, трафик увеличился, а сервер остался прежним. Посмотрите общую картину: сколько памяти всего, сколько занято, есть ли активный своп.
free -m
Если система постоянно в свопе и почти вся память занята бэкендом на нормальной нагрузке — это не «проблема Nginx», а сигнал, что ресурсов сервера уже мало. Тогда правка буферов даст копейки, а реально поможет оптимизация приложения или увеличение памяти сервера. Честно оцените: вы боретесь с неверной настройкой или упёрлись в потолок VPS. От этого зависит, крутить конфиг или добавлять ресурсы.
Профилактика: держим память под контролем
Чтобы память не становилась сюрпризом, настройте мониторинг потребления по процессам — тогда вы сразу видите, кто растёт: Nginx, PHP-FPM или приложение. Держите worker_processes auto, не раздувайте буферы без причины, рассчитывайте pm.max_children под реальную память сервера и размер воркера, включайте OPcache для PHP. Эти меры дают стабильный и предсказуемый расход.
И закладывайте запас RAM под пиковую нагрузку: сервер, живущий на пределе памяти в обычный день, свалится в своп в час пик и начнёт тормозить всё сразу. Если проект вырос, увеличение памяти сервера часто дешевле и надёжнее, чем бесконечная микрооптимизация конфигов. Помните главное: Nginx редко бывает настоящим виновником — начинайте диагностику с вопроса «а кто на самом деле ест память», и вы сэкономите много времени.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под сайтыОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Nginx правда может съедать много памяти?
Редко: сам Nginx очень экономен, его воркеры занимают единицы-десятки мегабайт. Обычно память ест бэкенд — PHP-FPM или приложение, — а Nginx лишь его обслуживает. Начните диагностику с ps aux --sort=-%mem.
Как правильно задать число воркеров Nginx?
Оставьте worker_processes auto — оно привяжет число к ядрам сервера. Раздувать worker_connections без нужды не стоит: реальный расход зависит от активных соединений, а не от лимита.
Память ест PHP-FPM — что делать?
Рассчитайте pm.max_children под доступную RAM и размер одного воркера, включите OPcache и оптимизируйте приложение. Это снижает расход эффективнее правки настроек Nginx.
Как оплатить более мощный сервер из России?
В MAATRIX — картой российского банка, через СБП, криптовалютой или токеном MAAT. Иностранная карта не нужна.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.