К содержанию
Siberian V

Сколько оперативной памяти нужно сайту на сервере

Сколько оперативной памяти нужно сайту: система, nginx, PHP-FPM, база данных и свободный запас в 2 ГБ

Единой цифры для всех сайтов нет, но угадывать её не приходится. Память сервера раскладывается на части: система, веб-сервер, пул процессов интерпретатора, база данных и запас. Каждую можно посчитать до аренды или измерить на работающей машине. Ниже — стартовые объёмы, формула для PHP-FPM и разбор того, что показывает free -h.

С чего начать: четыре типовых случая

Статика, блог на CMS, магазин и контейнеры тратят память по-разному. Для первого заказа годятся такие значения:

Что за сайтПамятьКуда она уходит
Статика: HTML, картинки, nginx512 МБ — 1 ГБСистема и веб-сервер; запас на всплеск посетителей
Блог или сайт на PHP с базой2 ГБПул PHP-FPM, буфер базы, кеш файлов
Магазин на готовом движке4 ГББольше воркеров PHP, крупнее база и индексы
Несколько сервисов в Docker4–8 ГБКаждый контейнер отдельно плюс база и кеш

Это ориентиры, а не нормы: два сайта на одном движке расходятся в памяти вдвое из-за плагинов и настроек базы. Общий разбор по всем ресурсам, включая процессор и диск, — в статье сколько ресурсов нужно VPS.

Гигабайт в карточке — это не гигабайт сайту

Когда в описании сервера написано «1 ГБ», сайту достаётся не весь гигабайт: часть забирают ядро, системные службы, веб-сервер и база. После установки Debian или Ubuntu без графики остаётся примерно 700–800 МБ — ещё до запуска PHP и СУБД.

Вторая часть, которую легко упустить, — кеш файлов. Ядро занимает свободную память под прочитанные страницы, чтобы не ходить на диск дважды. Эта память не отобрана у приложений: попросят — получат. Отсюда правило: смотрите не на занятую память, а на доступную.

Пул PHP-FPM: считайте процессы, а не страницы

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

память PHP-FPM ≈ pm.max_children × средний вес процесса

Для примера возьмём конфигурацию из Debian и Ubuntu: в файле www.conf по умолчанию стоит pm.max_children = 5. Если каждый процесс весит около 40 МБ, пул занимает порядка 200 МБ. Подняв лимит до 30 процессов ради «чтобы всем хватило», вы отдаёте PHP около 1,2 ГБ — половину памяти сервера с 2 ГБ. Вес процесса зависит от движка и плагинов, поэтому его измеряют:

ps -o rss=,cmd= -C php-fpm8.3 | sort -rn | head
pmap -x <PID> | tail -1

Имя процесса зависит от версии PHP, в примере — 8.3. pmap для выбранного процесса покажет общий объём, включая разделяемые библиотеки; сумма по ps поэтому слегка завышена, и это нормально для запаса.

Отдельно про memory_limit: в php.ini-production стоит 128M. Это потолок на один запрос, а не фактический расход — обычная страница тратит меньше. Но тяжёлая страница может упереться в потолок и упасть с ошибкой, поэтому лимит ставят выше реального веса одной страницы, а память считают по числу процессов.

База данных занимает больше, чем кажется

У MySQL и PostgreSQL главный потребитель памяти — не запросы, а буфер: прочитанные страницы данных и индексы. Чем он больше, тем реже база ходит на диск и тем быстрее отвечает сайт.

На выделенной машине под базу отдают большую часть памяти. Документация PostgreSQL называет разумной отправной точкой четверть памяти под shared_buffers и предупреждает, что выделять больше 40 % обычно бесполезно. Есть ещё work_mem — память на одну сортировку или соединение; на запрос она может понадобиться несколько раз, поэтому work_mem × max_connections даёт верхнюю оценку.

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

Как читать free -h и не пугаться цифры used

Первая команда для проверки памяти — free -h. Смысл столбцов разный:

Что видноЧто это значит
used высокий, buff/cache большой, available заметныйНорма: память занята файловым кешем и отдастся приложению
available меньше 10–15 % от totalЗапаса почти нет, скоро понадобится больше памяти
В строке Swap used растёт день за днёмСистема постоянно подкачивает страницы: RAM не хватает
В vmstat 1 5 столбцы si и so не нулевыеПодкачка идёт прямо сейчас, работа сайта замедляется

available — оценка памяти, которую получит новый процесс без ухода в swap. Именно по ней судят, хватает ли серверу RAM. Высокий used без активной подкачки не повод брать новый сервер. Разовый рост swap во время ночного бэкапа — нормальная страховка; плохо, когда swap занят постоянно и не освобождается: рабочему набору данных не хватает оперативной памяти, и увеличение файла подкачки только откладывает развязку.

Чем урезать память без замены сервера

Прежде чем брать конфигурацию крупнее, проверьте, что можно сделать на текущей:

Каждый шаг экономит десятки или сотни мегабайт, и иногда этого достаточно, чтобы дожить до планового роста. Что происходит с ресурсами при аренде и как проверить сервер в первый час, разобрано в статьях как выбрать VPS и первые 30 минут на сервере. Если сайт пока живёт на общем хостинге, сравнение форматов — в материале VPS или виртуальный хостинг.

Если процесс пропал: следы OOM

Когда память заканчивается вместе со swap, в работу вступает защита ядра — OOM killer. Она завершает один процесс, чтобы не остановилась вся система, и чаще всего выбирает самый крупный. Со стороны это выглядит странно: служба исчезла, а в её логе нет ни строчки об ошибке. След остаётся в журнале ядра:

journalctl -k | grep -i "killed process"
dmesg -T | grep -i "out of memory"

Строка «Out of memory: Killed process» означает, что дело не в коде приложения, а в нехватке памяти. Помогают два действия: снизить потребление по списку выше или взять более просторную машину. Перезапуск службы без этого ничего не меняет.

Если сервер держат ради подключения, а не сайта

Тот же сервер часто держат не ради страниц, а ради подключения с телефона и ноутбука: ресурсов нужно меньше, зато прибавляется дежурство — обновления, сертификаты, проверка после перезагрузки. Если администрировать машину ради одного подключения не хочется, в Siberian V есть приложение Karing: российские сайты открываются напрямую, остальное идёт через иностранный сервер.

Подключить

Частые вопросы

Сколько памяти нужно сайту на WordPress при 1000 посетителей в день?

Тысяча визитов в сутки — это несколько десятков в час и единицы одновременно открытых страниц. Небольшому сайту с базой на той же машине обычно хватает 2 ГБ: около 250 МБ забирает система, 300–500 МБ — база, остальное достаётся PHP-FPM. Точную цифру даёт замер: free -h в пик и вес процессов из ps.

Хватит ли серверу 512 МБ оперативной памяти?

Для статики на nginx — да, если на машине нет ничего лишнего. Для сайта на PHP с базой данных — нет: одна система займёт 150–250 МБ, база ещё несколько сотен, а пулу PHP-FPM нужно место под одновременные запросы. В таком случае памяти не хватит уже на этапе установки, и сервер начнёт уходить в swap.

Почему память занята на 90 %, а сайт работает нормально?

Потому что в used и buff/cache входит кеш файлов. Ядро держит в свободной памяти прочитанные страницы и отдаёт их приложению, как только оно попросит. Смотреть надо на available: если там остаётся заметный запас, высокой цифре used радоваться нечему и пугаться нечего.

Сколько памяти отдать MySQL или PostgreSQL на том же сервере?

Всё, что останется после системы, веб-сервера и пула PHP-FPM. На выделенной машине под базу отдают большую часть памяти: документация PostgreSQL называет разумной четверть под shared_buffers и предупреждает, что выше 40 % выделять бесполезно. Когда база делит сервер с сайтом, буфер приходится урезать, иначе процессы отнимут память друг у друга.

Что будет, если памяти не хватит?

Сначала система начнёт подкачивать страницы в swap, и сайт замедлится. Когда закончится и swap, сработает защита ядра: она завершит один из процессов, обычно самый прожорливый. Со стороны это выглядит как сервис, который пропал без ошибки в своём логе; след остаётся в журнале ядра, его показывает journalctl -k с поиском по слову killed.