Сколько RAM нужно для ERPNext
На форумах 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-socketio | 40–70 МБ | 60–100 МБ | Число активных realtime-подключений |
| MariaDB | 300–500 МБ | до innodb_buffer_pool_size | Объём данных, число одновременных соединений |
| Redis (cache + queue) | 15–40 МБ суммарно | растёт с длиной очереди | Обычно не главный потребитель |
| nginx + system | 150–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 ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →