Сколько оперативной памяти нужно сайту на сервере
Единой цифры для всех сайтов нет, но угадывать её не приходится. Память сервера раскладывается на части: система, веб-сервер, пул процессов интерпретатора, база данных и запас. Каждую можно посчитать до аренды или измерить на работающей машине. Ниже — стартовые объёмы, формула для PHP-FPM и разбор того, что показывает free -h.
С чего начать: четыре типовых случая
Статика, блог на CMS, магазин и контейнеры тратят память по-разному. Для первого заказа годятся такие значения:
| Что за сайт | Память | Куда она уходит |
|---|---|---|
| Статика: HTML, картинки, nginx | 512 МБ — 1 ГБ | Система и веб-сервер; запас на всплеск посетителей |
| Блог или сайт на PHP с базой | 2 ГБ | Пул PHP-FPM, буфер базы, кеш файлов |
| Магазин на готовом движке | 4 ГБ | Больше воркеров PHP, крупнее база и индексы |
| Несколько сервисов в Docker | 4–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 занят постоянно и не освобождается: рабочему набору данных не хватает оперативной памяти, и увеличение файла подкачки только откладывает развязку.
Чем урезать память без замены сервера
Прежде чем брать конфигурацию крупнее, проверьте, что можно сделать на текущей:
- привести
pm.max_childrenв соответствие с остатком памяти после базы и системы; - включить кеш страниц на веб-сервере: готовый HTML отдаётся без запуска PHP;
- отключить неиспользуемые службы: второй веб-сервер, лишние демоны, панель «на попробовать»;
- задать лимиты контейнерам —
--memoryвdocker runилиmem_limitв Compose, — чтобы один сервис не забирал память у остальных; - ограничить службу через systemd:
MemoryMaxв юните не даст выйти за отведённый объём (расход по службам показываетsystemd-cgtop).
Каждый шаг экономит десятки или сотни мегабайт, и иногда этого достаточно, чтобы дожить до планового роста. Что происходит с ресурсами при аренде и как проверить сервер в первый час, разобрано в статьях как выбрать 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.