Сколько RAM нужно для Payload CMS
Payload CMS продают как «TypeScript-first» headless-CMS, где схема контента описывается кодом, а не собирается мышкой в админке — это удобно разработчику, но обманчиво просто для того, кто планирует сервер под неё. В официальной документации нет чёткой цифры минимальной RAM, а форумы полны жалоб на упавший процесс ровно во время next build или после третьей загрузки изображений через media-коллекцию. Разберём, из чего на самом деле складывается память Payload: рантайм, сборка админки и база данных живут не по одним и тем же правилам, и если считать только «сервер вроде запустился» — легко промахнуться с тарифом.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Почему у Payload нет одной цифры RAM
Payload с версии 3.x — это не отдельный сервер, а пакет, который устанавливается прямо в Next.js-приложение: административная панель рендерится через App Router тем же процессом, что отдаёт ваш сайт или API. Отсюда и главная особенность потребления памяти — она не постоянна, а скачет между тремя разными режимами:
- Разработка (
next dev) — постоянно держит в памяти дерево модулей, кеш Fast Refresh, TypeScript-компилятор дляpayload.config.ts. Самый прожорливый режим, но он живёт только на вашей машине или CI, не на проде. - Сборка (
next build) — кратковременный, но самый опасный пик: Next.js собирает статику, генерирует типы Payload из конфига коллекций, оптимизирует изображения черезsharp. Именно здесь чаще всего падает процесс на маленьком VPS. - Продакшн-рантайм (
next startили standalone-сервер) — самый лёгкий режим: держит уже собранные страницы и обслуживает API/админку по запросу.
Путать эти три цифры — типичная ошибка: сервер, который спокойно тянет рантайм на 1 ГБ, может не пережить деплой с пересборкой на том же объёме.
Node.js-процесс: что жрёт память само по себе
Пустое Node.js-приложение с подключённым Payload и парой коллекций в состоянии покоя занимает ориентировочно 200–350 МБ — это V8-heap плюс сам движок Payload (схема коллекций, access control, hooks, локализация, если включена). Цифра растёт с числом коллекций, полей richText (Lexical-редактор тянет собственное дерево узлов) и активных плагинов — official-плагины вроде @payloadcms/plugin-seo или plugin-search добавляют не так много, но каждый новый collection type с вложенными blocks увеличивает объём схемы, которую Payload держит в памяти для валидации.
Отдельная статья расходов — sharp, библиотека обработки изображений, которую Payload использует для генерации sizes (thumbnail, card, og-image и т.д.) при загрузке в media-коллекцию. Обработка одного крупного изображения (условно от 10-15 МБ, RAW-фото с телефона) может кратковременно потребовать несколько сотен мегабайт сверх базового потребления — это нормально для sharp, но на VPS с 1 ГБ RAM без swap такой скачок иногда роняет процесс через OOM killer.
# ограничить heap самого Node.js процесса Payload
NODE_OPTIONS="--max-old-space-size=1024" node server.js
Это не экономит память сама по себе, а задаёт потолок, при котором Node аккуратно освобождает память через garbage collector вместо неконтролируемого роста — полезно, чтобы процесс не тянул с собой соседние сервисы на общем сервере.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверБаза данных: Postgres против MongoDB по памяти
Payload 3.x поддерживает три адаптера БД — MongoDB, PostgreSQL и SQLite, и выбор напрямую влияет на бюджет RAM сервера.
| Адаптер | Память БД в простое | Особенности |
|---|---|---|
| SQLite | практически 0 (файл на диске) | подходит для одиночных сайтов и MVP, но плохо переживает конкурентную запись |
| PostgreSQL | ~50–100 МБ на пустой базе, растёт с shared_buffers | лучший баланс для продакшна, гибкие индексы для richText-полей |
| MongoDB | ~200–300 МБ в простое | нативнее ложится на схему Payload (JSON-документы), но сама СУБД прожорливее |
Если у вас уже есть PostgreSQL, настроенный на VPS, логично взять адаптер @payloadcms/db-postgres — вы получите привычные бэкапы и мониторинг и не добавите второй тяжёлый процесс на сервер. MongoDB имеет смысл, если проект изначально проектировался вокруг документной модели или мигрирует со старой версии Payload (2.x была MongoDB-only).
Для расчёта общего бюджета сервера: RAM Node.js-процесса и RAM базы данных не пересекаются, их нужно складывать, а не выбирать по большей. Плюс к этому — прослойка ОС, SSH, systemd, возможно nginx перед приложением: закладывайте на это отдельные 150–250 МБ.
Таблица минимальных конфигураций
Ориентировочные цифры для разных сценариев — реальное потребление зависит от числа коллекций, richText-полей, объёма и частоты загрузки медиа. Проверяйте на своём проекте через free -h и htop после недели работы под реальной нагрузкой.
| Сценарий | RAM | vCPU | Комментарий |
|---|---|---|---|
| MVP / лендинг, SQLite, редкие правки | 2 ГБ | 1-2 | сборку лучше делать не на этом же сервере или заранее выделять swap |
| Блог/каталог, Postgres, до 10 коллекций | 4 ГБ | 2 | комфортный минимум для стабильной работы + сборка на месте |
| Средний проект, richText + media, активные редакторы | 8 ГБ | 2-4 | запас под пики sharp и параллельные запросы к админке |
| Крупный мультиязычный проект, MongoDB, много blocks-полей | 16 ГБ | 4+ | локализация и вложенные blocks заметно увеличивают вес схемы в памяти |
Если проект живёт на одном сервере целиком (Payload + Postgres/Mongo + nginx), закладывайте на один уровень выше, чем «голый» рантайм — совмещённая установка почти всегда требует больше буфера, чем сумма минимумов по документации каждого компонента.
Как не словить OOM на сборке
Самая частая жалоба в комьюнити Payload — не «медленно работает», а «падает при деплое». Причина почти всегда одна: next build на сервере с 1-2 ГБ RAM и без свопа. Несколько практических приёмов:
- Собирайте не на проде. Соберите приложение в CI (GitHub Actions, GitLab CI) или на отдельной build-машине, а на сервер выкатывайте уже готовый
.next/standalone— рантайм после сборки требует в разы меньше памяти, чем сама сборка. - Добавьте swap, если сборка всё же идёт локально. Даже 2 ГБ файла подкачки не спасут от деградации по скорости, но спасут процесс от убийства OOM killer'ом в момент пика.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
- Ограничьте heap сборки явно, если процесс собирается прямо на сервере:
NODE_OPTIONS="--max-old-space-size=2048" npx next build
- Проверьте параллелизм sharp. По умолчанию sharp может использовать несколько потоков для обработки изображений — на слабом сервере стоит ограничить это переменной окружения
UV_THREADPOOL_SIZEили обрабатывать медиа партиями, а не заливать сотни файлов разом при первом импорте контента.
Если падения всё равно случаются на этапе рантайма, а не сборки — вероятно, дело не в Payload, а в общей нехватке памяти сервера; общий подход к диагностике описан в статье что делать при нехватке RAM.
Эксплуатация: connection pool, PM2 и мониторинг
После деплоя основной риск смещается с пиков сборки на постепенный рост потребления под нагрузкой — типичная картина для любого Node.js-приложения с долгоживущим процессом.
Пул подключений к базе. Каждое открытое соединение к Postgres или MongoDB держит собственный буфер на стороне и клиента, и сервера БД. Для Payload с адаптером db-postgres пул настраивается через pool в конфиге:
// payload.config.ts
import { postgresAdapter } from '@payloadcms/db-postgres'
export default buildConfig({
db: postgresAdapter({
pool: {
connectionString: process.env.DATABASE_URI,
max: 10, // не завышайте на маленьком сервере
},
}),
// ...
})
Значение max по умолчанию в некоторых конфигурациях выше, чем нужно небольшому проекту — 10 одновременных соединений с запасом хватает для сайта с умеренной посещаемостью админки, а каждое лишнее соединение — это лишние мегабайты на стороне Postgres.
PM2 с автоперезапуском по памяти. Если процесс всё же периодически «пухнет» (утечки в кастомных hooks — не редкость), не гоняйтесь за идеальным исправлением бага прямо сейчас, а поставьте защитный порог:
pm2 start npm --name payload -- run start
pm2 set pm2:max_memory_restart 1200M
Это не решение проблемы утечки, а страховка: процесс перезапустится сам при превышении лимита, вместо того чтобы уронить сервер целиком через OOM killer, который может задеть и соседние сервисы.
Мониторинг. Минимальный набор — free -h раз в день на первую неделю после запуска и алерт по свободной памяти ниже 15%. Если держите на сервере что-то ещё — сравните подход в статье сколько RAM нужно для WordPress, если рассматриваете альтернативные CMS для того же проекта, или посмотрите на сравнение с Strapi, если ещё выбираете между headless-решениями.
Локализация и blocks: скрытые множители памяти
Две особенности Payload, которые редко закладывают в расчёт заранее — локализация (localization в конфиге) и blocks-поля (flexible content, layout builder).
Локализация не дублирует Node.js-процесс, но увеличивает объём каждого документа, который проходит через валидацию и hooks: если у вас 5 локалей и richText-поле переведено на все, in-memory представление документа при сохранении и рендере админки будет в несколько раз тяжелее, чем в одноязычном проекте. На практике это не всегда заметно на CPU, но ощутимо на пиках heap при массовом импорте контента через скрипты — если делаете миграцию тысяч документов, запускайте её порциями, а не одним batch-скриптом на весь датасет.
Blocks-поля (вложенные блоки контента, аналог ACF Flexible Content в WordPress) увеличивают вес схемы, которую Payload держит в памяти для генерации TypeScript-типов и валидации на каждый запрос сохранения. Проект с 20+ типами блоков, вложенными друг в друга на 2-3 уровня, ощутимо тяжелее по памяти схемы, чем проект с плоской структурой из тех же 20 полей — разница обычно в десятках, а не в сотнях мегабайт, но на границе тарифа 2 ГБ это может стать решающим фактором.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Хватит ли 1 ГБ RAM для Payload CMS?
Для рантайма уже собранного standalone-приложения с SQLite и без нагрузки — теоретически да, но без запаса на сборку, swap и рост базы. Для боевого проекта это рискованная конфигурация; 2 ГБ — более реалистичный минимум.
Payload CMS требует больше памяти, чем WordPress?
Node.js-процесс сам по себе обычно легче, чем связка PHP-FPM + MySQL под нагрузкой, но сборка через Next.js (next build) — заметно тяжелее разовой операции, чем что-либо в стандартном WordPress. Для голого рантайма Payload часто экономичнее, для деплоя — наоборот.
Можно ли собирать Next.js/Payload на том же сервере, где крутится продакшн?
Можно, но закладывайте отдельный буфер под пик сборки или переносите сборку в CI — это снимает риск падения продакшн-процесса из-за параллельной пересборки.
MongoDB или PostgreSQL — что экономичнее по RAM?
PostgreSQL в простое обычно легче MongoDB на 100-200 МБ, но разница нивелируется при росте базы и настройке shared_buffers/WiredTiger cache под нагрузку — выбирайте адаптер по архитектуре проекта, а не только по памяти.
Как понять, что серверу не хватает RAM именно из-за Payload, а не БД?
Смотрите htop во время сборки и во время обычной работы отдельно — если пик приходится строго на момент next build или загрузки изображения, дело в рантайме/sharp; если память растёт постоянно и коррелирует с размером таблиц — смотрите в сторону БД и её кеша.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →