MAATRIX / Блог / Сколько RAM нужно для ERPNext

Сколько RAM нужно для ERPNext

MAATRIX

На форумах Frappe/ERPNext цифры расходятся вдвое-втрое: кто-то поднял тестовый стенд на 2 ГБ и доволен, кто-то с двадцатью пользователями упирается в OOM-killer на 8 ГБ. Обе истории правдивы — ERPNext не одно приложение, а связка из шести-восьми процессов, каждый умеет отдельно взлетать по памяти. Разберём, из чего складывается расход, как замерить его на своей системе и что закладывать под конкретное число пользователей.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Короткий ответ: сколько закладывать

Цифры для одного bench с одним сайтом на Ubuntu 24.04, стек nginx + MariaDB 10.6/11 + Redis + gunicorn + RQ-воркеры, версия Frappe/ERPNext 15. Модули на старте — Accounts, Selling, Buying, Stock (стандартный набор при установке).

RAMКому подходитЧестный комментарий
2 ГБТолько демо/установка одного пользователяbench setup production пройдёт, но первый импорт CSV или отчёт с джойнами уйдёт в своп
4 ГБ3–8 пользователей, базовые модулиРабочий минимум для малого бизнеса, без HR/Manufacturing
8 ГБ10–25 пользователей, + HR, Payroll, CRMКомфортный вариант для большинства внедрений
16 ГБ25–60 пользователей, + Manufacturing, несколько компанийManufacturing тянет за собой тяжёлые отчёты по BOM и MRP
32 ГБ60–150 пользователей, несколько сайтов на одном benchАктуально для мультитенантных инсталляций и кастомных приложений поверх Frappe

Это ориентир, не гарантия — реальный расход может отличаться на 30–50% в зависимости от того, сколько кастомных Doctype и Server Script навешано поверх стандарта: каждый серверный скрипт выполняется внутри того же Python-процесса, что и остальной код.

Из чего состоит стек ERPNext и почему это не «PHP + MySQL»

ERPNext построен на фреймворке Frappe (Python + MariaDB), и в проде это не два процесса, а целый набор, которым управляет supervisor после bench setup production: gunicorn для веб-запросов, три типа RQ-воркеров (default/short/long) для фоновых задач, отдельный процесс-планировщик, Node.js для realtime-уведомлений через socketio, два инстанса Redis (кеш и очередь), сама MariaDB и nginx перед всем этим как reverse proxy.

Ключевая деталь, которая ломает интуицию «Python-процесс — это дёшево»: и gunicorn-воркеры, и каждый RQ-воркер поднимают полный Frappe framework — импортируют все установленные приложения (frappe, erpnext, ваши кастомные apps), загружают метаданные Doctype, hooks, схему прав доступа. Воркер, который просто ждёт задачу в очереди, весит почти столько же, сколько воркер с открытым веб-соединением — 150–300 МБ, а не 20–30, как у типичного stateless-обработчика.

Список процессов на своём сервере — sudo supervisorctl status:

frappe-bench-web:frappe-bench-frappe-web                     RUNNING   pid 1822
frappe-bench-workers:frappe-bench-frappe-default-worker-0    RUNNING   pid 1830
frappe-bench-workers:frappe-bench-frappe-short-worker-0      RUNNING   pid 1834
frappe-bench-workers:frappe-bench-frappe-long-worker-0       RUNNING   pid 1838
frappe-bench-schedule:frappe-bench-frappe-schedule           RUNNING   pid 1842
frappe-bench-node-socketio:frappe-bench-frappe-node-socketio RUNNING  pid 1846
frappe-bench-redis-cache:frappe-bench-frappe-redis-cache     RUNNING   pid 1810
frappe-bench-redis-queue:frappe-bench-frappe-redis-queue     RUNNING   pid 1814

Восемь процессов на голом сайте ещё до того, как в него залили хоть одну накладную.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Что реально ест память: разбор по процессам

Ориентировочные значения RSS на сайте с базовыми модулями и 1,5–2 ГБ данных в MariaDB. Ваши цифры будут отличаться — снимайте свои через smem, ниже показано как.

ПроцессВ покоеПод нагрузкойОт чего зависит
gunicorn-воркер130–180 МБ200–350 МБЧисло gunicorn_workers, установленные custom apps
RQ default-воркер120–160 МБдо 400 МБОтчёты, массовая печать, email-рассылка через очередь
RQ short/long-воркер110–150 МБзависит от задачиИмпорт данных, пересчёт остатков склада, MRP
schedule-процесс100–140 МБкратковременные всплескиПериодические задачи (hooks.py: scheduler_events)
node-socketio40–70 МБ60–100 МБЧисло активных realtime-подключений
MariaDB300–500 МБдо innodb_buffer_pool_sizeОбъём данных, число одновременных соединений
Redis (cache + queue)15–40 МБ суммарнорастёт с длиной очередиОбычно не главный потребитель
nginx + system150–250 МБ250–350 МББазовый оверхед ОС

Главный вывод из таблицы: на голом ERPNext без единого пользователя уже занято 1–1,3 ГБ только на дежурные процессы. Это не баг конфигурации, а цена архитектуры «много воркеров с полным контекстом фреймворка» в обмен на изоляцию очередей.

Что двигает расход при росте пользователей и модулей

Число пользователей само по себе не главный множитель — как и с большинством веб-приложений, одновременно активны обычно 15–25% от списочного состава. На память сильнее давят три вещи.

Количество gunicorn-воркеров. bench setup production считает их по стандартной формуле gunicorn — примерно 2 × число ядер + 1 — и записывает в sites/common_site_config.json. На 4-ядерной машине это девять воркеров, то есть уже 1,2–1,8 ГБ только под веб-слой ("gunicorn_workers": 9, "background_workers": 4 в конфиге).

Тяжёлые модули. Manufacturing (BOM explosion, MRP-планирование), Payroll и Regional/Localization-приложения не столько держат данные в памяти постоянно, сколько порождают редкие, но крупные всплески в RQ long-воркерах — отчёт по многоуровневой спецификации на несколько тысяч позиций легко возьмёт лишние 200–400 МБ на время расчёта.

Кастомные Doctype и Server Script. Каждый добавленный Doctype увеличивает метаданные, которые Frappe кеширует в памяти каждого воркера при старте. Для собственных 20–50 Doctype это заметно меньше, чем сама база ERPNext (300+ стандартных), но при активном использовании клиентских скриптов и вебхуков возможны утечки в долгоживущих воркерах — их лечит bench restart по расписанию, а не наращивание RAM.

Несколько сайтов на одном bench. Frappe умеет держать multi-tenant — сайты делят один набор gunicorn/RQ процессов, но у каждого своя база. Второй сайт добавляет не полный комплект процессов заново, а прирост в среднем 300–600 МБ на активные соединения и кеш — логика похожая на разбор ресурсов VPS для 1С в облаке: считать нужно не число «инсталляций», а число одновременных сессий.

Как замерить память на своём сервере

Не берите цифры из этой статьи как окончательные — снимите свои.

Кто сколько ест прямо сейчас, с честной разбивкой разделяемой памяти, и пик по cgroup (Ubuntu 24.04, cgroup v2) — тарифицировать нужно по худшему моменту, не по текущему:

sudo apt install -y smem
sudo smem -t -k -P 'gunicorn|rq|node|mariadbd|redis' -c 'name pss rss'
cat /sys/fs/cgroup/system.slice/supervisor.service/memory.peak

Что происходит в очередях RQ прямо сейчас:

bench --site your-site.local doctor

Команда покажет число задач в очередях default/short/long — если очередь стабильно растёт, дело в недостатке *воркеров*, а не памяти на существующие.

Буферный пул MariaDB — используется ли он вообще:

SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) AS size_mb
FROM information_schema.tables WHERE table_schema = 'your_erpnext_db';

Если размер базы меньше innodb_buffer_pool_size — буфер выставлен щедро, можно смело уменьшать при нехватке памяти в другом месте. Подробнее про саму настройку — в статье MariaDB на VPS: установка и настройка.

Доступная память, а не «свободная»: free -m, колонка available, не free — Linux разумно отдаёт неиспользуемую память под дисковый кеш MariaDB и файлов сайта, и это нормально, а не признак нехватки.

Тюнинг под ограниченную память

Если тариф уже куплен, вот что реально снижает расход без потери функциональности.

Уменьшить число gunicorn-воркеров. Формула 2 × ядра + 1 рассчитана на высокую параллельность, которая малому бизнесу часто не нужна. Для 2 vCPU и до десяти пользователей достаточно 2–3:

bench --site your-site.local set-config gunicorn_workers 3
bench --site your-site.local set-config background_workers 1
bench restart

Ограничить буферный пул MariaDB осознанно, а не оставлять автонастройку по умолчанию (на некоторых образах она ставит 50–75% RAM под innodb — для мультисервисного сервера слишком много): innodb_buffer_pool_size = 512M, max_connections = 60, performance_schema = OFF в /etc/mysql/mariadb.conf.d/50-server.cnf.

Не плодить лишние RQ-воркеры вручную. Если очереди короткие, background_workers: 1 в common_site_config.json держит по одному воркеру на тип задачи вместо нескольких дублей.

Добавить swap как подушку, не как замену RAM. На 4 ГБ ERPNext иногда упирается в кратковременный пик при импорте — 2 ГБ swap (fallocate -l 2G /swapfile && mkswap /swapfile && swapon /swapfile, строка в /etc/fstab, vm.swappiness=10) спасают от OOM-killer ценой замедления именно в этот момент.

Перезапускать bench по расписанию, если видите постепенный рост RSS у long-воркеров — типичный симптом накопления состояния в долгоживущих Python-процессах при активных кастомных скриптах:

0 4 * * * cd /home/frappe/frappe-bench && bench restart

Если ERPNext развёрнут через Docker Compose (официальный frappe_docker), логика та же, но лимиты удобнее задавать явно на уровне сервисов — общий подход к продакшен-конфигурации разобран в статье про Docker Compose для продакшена.

Какой сервер под ERPNext взять в MAATRIX

Тест и знакомство: 2 vCPU, 4 ГБ RAM, 40 ГБ NVMe. Хватит поставить ERPNext, пройти мастер настройки, завести пару пользователей и посмотреть, подходят ли модули. Для реальной эксплуатации даже небольшой командой — тесно: gunicorn и RQ-воркеры на дежурстве уже занимают половину памяти.

Малый и средний бизнес, 5–20 пользователей: 4 vCPU, 8 ГБ RAM, 80–160 ГБ NVMe. Комфортный вариант для стандартного набора модулей — Accounts, Selling, Buying, Stock, CRM, базовый HR. Четыре ядра важны не меньше памяти: gunicorn-воркеры и MRP-расчёты процессорозависимы и на двух ядрах конкурируют друг с другом в моменты пиковой нагрузки.

Manufacturing, Payroll на большой штат, несколько компаний: 6–8 vCPU, 16 ГБ RAM, от 160 ГБ NVMe. Запас нужен не под фон, а под редкие тяжёлые операции — пересчёт MRP по всей номенклатуре, массовая печать зарплатных ведомостей, консолидированные отчёты по нескольким компаниям.

Локация. Для внутрироссийской команды логичнее российская площадка — меньше задержка на каждый AJAX-запрос интерфейса, который живёт на постоянном обмене с сервером (список задач, socketio-уведомления, автосохранение форм). Данные по 152-ФЗ — тоже аргумент в пользу РФ; для команд с частью сотрудников за рубежом разумный компромисс — Лондон.

ERPNext из каталога apps.maatrix.io разворачивается на сервере автоматически при заказе — bench, MariaDB, Redis и supervisor настраиваются без ручной установки, доступ и пароль администратора приходят в личный кабинет. Донастройка под свою нагрузку — число воркеров, буферный пул базы — по инструкциям выше. Оплата принимается картами российских банков, по СБП, криптовалютой и токеном MAAT, включая зарубежные локации без иностранной карты.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

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

Хватит ли 4 ГБ RAM для ERPNext, если пользователь один?

Формально да, но с оговорками: уменьшите gunicorn_workers до 2, background_workers до 1, innodb_buffer_pool_size до 256–384 МБ и добавьте 2 ГБ swap — импорт большого CSV или bench install-app это оценят.

Почему ERPNext ест память даже когда никто не работает?

Восемь дежурных процессов (gunicorn, три RQ-воркера, schedule, node-socketio, два Redis, MariaDB) держат базовый оверхед 1–1,3 ГБ независимо от активности — цена архитектуры Frappe с изолированными очередями, а не утечка.

Manufacturing и Payroll точно требуют больше RAM, чем базовые модули?

Сами модули почти ничего не резервируют постоянно, но порождают редкие тяжёлые задачи — MRP-пересчёт, массовый расчёт зарплаты, — которые на несколько минут поднимают конкретный RQ-воркер на 200–400 МБ. Важнее не общий объём RAM, а пара ГБ запаса под такой пик.

Что упадёт первым при нехватке памяти — ERPNext или MariaDB?

OOM-killer обычно выбирает процесс с наибольшим потреблением на момент пика, а это чаще всего mariadbd, а не виновный в скачке RQ-воркер. Если сервер «сам перезагружает базу» без причины в логах ERPNext — смотрите dmesg -T | grep -i kill.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →