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

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

MAATRIX

Odoo — модульная ERP/CRM: продажи, склад, бухгалтерия, производство в одной системе, self-hosted. Проблема в том, что официальная документация даёт формулу расчёта памяти, а не готовый ответ «бери 8 ГБ и не думай» — и в итоге либо покупают сервер с запасом в три раза, либо получают OOM killer через неделю после запуска склада и бухгалтерии одновременно. Разберём, откуда берётся аппетит Odoo к RAM и как посчитать нужный объём под свою нагрузку.

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

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

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

Как Odoo расходует память

Odoo — не один процесс, а пул процессов (workers), которые Gunicorn поднимает поверх Python. Каждый worker — это отдельный процесс с собственным интерпретатором Python, загруженными модулями ORM и открытым соединением к PostgreSQL. Память не расшаривается между workers почти никак — это классическая multiprocessing-модель, а не многопоточная.

Из-за этого память Odoo растёт не линейно с числом пользователей, а линейно с числом workers, которые вы сконфигурировали — и число это вы задаёте сами в odoo.conf. Мало workers — сервер экономит память, но запросы выстраиваются в очередь. Много workers — параллелизм выше, но каждый лишний процесс это ещё 150–1000+ МБ, в зависимости от того, что он в этот момент делает: простой список контактов из CRM ест немного, а формирование PDF-отчёта по остаткам склада на 50 000 позиций может на время раздуть worker на гигабайт и больше.

Отдельная статья расходов — PostgreSQL, который у Odoo не встроенный, а внешний процесс со своим бюджетом памяти (shared_buffers, work_mem, кэш ОС под файлы БД). Его нужно считать отдельно от памяти самого Odoo, и об этом ниже.

Формула расчёта из документации Odoo

У Odoo есть официальная методика расчёта workers и памяти под них (раздел деплоя в документации). Коротко:

workers = (число ядер CPU × 2) + 1

Например, на 4-ядерном сервере — 9 workers. Из них 1-2 стоит отвести под cron (max_cron_threads), остальные — под HTTP-запросы. Дальше документация предлагает грубое эмпирическое правило по памяти на worker:

  • ~80% запросов — «лёгкие», в среднем около 150 МБ на worker;
  • ~20% запросов — «тяжёлые» (отчёты, экспорты, импорт данных), в среднем около 1 ГБ на worker.

Отсюда ориентировочная формула:

RAM на workers ≈ workers × (0.8 × 150 МБ + 0.2 × 1024 МБ)
             ≈ workers × 325 МБ

Для 9 workers это около 3 ГБ только на пул процессов Odoo, без учёта PostgreSQL, ОС и файлового кэша. Это именно ориентир из документации Odoo, а не измеренный бенчмарк — на реальном проекте цифра зависит от того, сколько у вас установлено модулей, насколько тяжёлые кастомные вычисления в них зашиты и сколько данных в базе. Держите готовность к тому, что фактическое потребление будет отличаться в 1.5–2 раза в любую сторону.

Второй ограничитель — limit_memory_soft и limit_memory_hard в odoo.conf. Soft-лимит (по умолчанию около 2 ГБ) — при превышении worker завершает текущий запрос и перезапускается; hard-лимит (около 2.5 ГБ) — worker убивается принудительно. Это защита от утечек и завышенных пиков, а не настройка «экономии» памяти — снижать её без причины не стоит, иначе тяжёлые отчёты начнут падать.

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

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

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

Сколько RAM нужно по сценариям использования

Ниже — ориентировочные пороги для типовых сценариев. Это отправная точка для выбора тарифа, а не гарантия — количество и «тяжесть» установленных модулей (Manufacturing и Accounting голоднее, чем чистый CRM) сдвигают цифры заметно.

СценарийПользователей одновременноvCPURAMWorkers
Тест / изучение Odoo11-22-4 ГБ0 (dev-режим, без multiprocessing)
Малый бизнес, базовые модули (Продажи, CRM, Контакты)5-1524-8 ГБ3-5
Средний бизнес, + Склад, Бухгалтерия15-4048-16 ГБ5-9
Производство, много кастомных модулей40-1006-816-32 ГБ9-13
Крупная установка, отдельный сервер под Odoo100+8+32 ГБ+Odoo и PostgreSQL — на разных серверах

Для тестового режима без workers (workers = 0) Odoo работает в однопроцессном режиме — это удобно для разработки, но непригодно для прод-нагрузки с несколькими одновременными пользователями: один медленный запрос блокирует остальных.

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

PostgreSQL: отдельный бюджет памяти

Odoo хранит все данные в PostgreSQL, и это отдельный процесс со своим потреблением RAM, независимым от workers Odoo. Стандартные ориентиры для тюнинга PostgreSQL под Odoo:

shared_buffers = 25% от RAM сервера
effective_cache_size = 50-75% от RAM сервера
work_mem = RAM / (max_connections × 3), обычно 4-16 МБ
maintenance_work_mem = 5-10% от RAM (но не больше 1-2 ГБ)

На сервере с 8 ГБ RAM, где вы уже отвели 3-4 ГБ под workers Odoo, для PostgreSQL разумно оставить shared_buffers не 2 ГБ (25% от полного объёма), а 1-1.5 ГБ — от факта, а не от теоретической четверти, иначе сумма аппетитов PostgreSQL и Odoo не влезет в сервер. Как посчитать баланс и что проверить после изменения конфига — в отдельном разборе про тюнинг PostgreSQL; базовую установку под Odoo — в статье про установку PostgreSQL на VPS.

Число одновременных подключений к PostgreSQL завязано на число workers Odoo: обычно db_maxconn берут равным числу workers плюс небольшой запас (2-3 соединения на служебные нужды). Если PostgreSQL стоит на том же сервере, что и Odoo, — это не проблема, но подключения тоже стоят памяти (по несколько МБ каждое, плюс work_mem на сложные запросы), и при расчёте бюджета их нельзя игнорировать.

Docker-развёртывание и лимиты памяти

При развёртывании Odoo через docker-compose (официальный образ odoo + postgres) память workers и PostgreSQL считается точно так же, но добавляется вопрос лимитов на уровне контейнеров:

services:
  odoo:
    image: odoo:17
    mem_limit: 4g
    environment:
      - HOST=db
      - USER=odoo
      - PASSWORD=odoo_pass
    volumes:
      - odoo-data:/var/lib/odoo
      - ./config:/etc/odoo
    depends_on:
      - db
  db:
    image: postgres:15
    mem_limit: 2g
    environment:
      - POSTGRES_USER=odoo
      - POSTGRES_PASSWORD=odoo_pass
    volumes:
      - db-data:/var/lib/postgresql/data

Здесь легко ошибиться дважды. Во-первых, mem_limit контейнера Odoo должен покрывать не средний, а пиковый расход всех workers сразу — если поставить лимит впритык к среднему потреблению, тяжёлый отчёт периодически будет убивать контейнер через cgroup OOM killer, а не через limit_memory_hard самого Odoo (это разные механизмы, и cgroup срабатывает жёстче — без плавного перезапуска worker). Во-вторых, сумма mem_limit всех сервисов в docker-compose.yml не должна превышать RAM сервера за вычетом памяти под ОС и файловый кэш — иначе при одновременной нагрузке на оба контейнера сервер уходит в своп или в системный OOM killer уже на уровне хоста. Общие принципы выставления лимитов подробнее разобраны в статье про лимиты CPU и памяти в Docker.

Как понять, что памяти не хватает

Признаки нехватки RAM под Odoo редко выглядят как явная ошибка — чаще это медленная деградация:

# Общая картина по памяти и свопу
free -h

# Кто ест память прямо сейчас
htop

# Убивал ли ядро процессы по нехватке памяти
dmesg | grep -i "out of memory"
journalctl -k | grep -i "killed process"

# Для Docker — реальное потребление по контейнерам
docker stats --no-stream

Если в dmesg регулярно встречается Killed process ... (odoo) — это прямой сигнал, что workers пробивают доступную память и ядро (не сам Odoo) их останавливает. Отдельно проверьте лог Odoo на строки вида WorkerHTTP (pid). Killing (hard limit reached) — это уже собственный механизм Odoo, более щадящий, но частое срабатывание всё равно означает, что limit_memory_hard подобран близко к пределу сервера.

Быстрые меры без апгрейда сервера: снизить число workers (уменьшит параллелизм, но и пиковую память), проверить, не висят ли неиспользуемые модули в базе (лишний установленный модуль — это не только диск, но и память на его ORM-модели), ограничить work_mem в PostgreSQL, если тяжёлые запросы конкурируют за память с workers Odoo. Своп на сервере с Odoo стоит держать как аварийную подушку на случай кратковременного пика (см. когда нужен swap-файл), но не как постоянную опору — если Odoo регулярно уходит в своп, это уже сигнал брать план с большим объёмом RAM, а не жить в своп-файле: диск на порядок медленнее RAM, и под свопом интерфейс Odoo ощутимо тормозит.

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

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

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

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

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

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

Хватит ли 2 ГБ RAM для Odoo?

Для знакомства с системой в dev-режиме (workers = 0, один пользователь) — да, но впритык: Odoo плюс PostgreSQL плюс ОС легко съедают весь объём при первом же тяжёлом отчёте. Для постоянной работы даже с одним активным пользователем комфортнее 4 ГБ.

Сколько RAM ест один пользователь Odoo?

Так вопрос не работает — память расходуется на workers, а не на пользователей напрямую. Одновременных пользователей условно соотносят с workers по правилу «около 6 активных пользователей на 1 worker», но при тяжёлых модулях (Manufacturing, множественные отчёты) соотношение может быть заметно ниже.

Нужно ли выносить PostgreSQL на отдельный сервер?

До сотни активных пользователей обычно нет смысла — совмещённая установка проще в администрировании. Разносить стоит, когда узкое место — именно диск и I/O базы (например, при интенсивной аналитике поверх больших таблиц), а не общий объём RAM.

Как узнать текущее число workers у уже запущенного Odoo?

Проверьте odoo.conf на параметр workers или посмотрите список процессов: ps aux | grep odoo покажет число процессов odoo-bin — их количество примерно и есть workers плюс cron-поток.

Влияет ли версия Odoo (16/17/18) на потребление памяти?

Незначительно относительно эффекта от числа установленных модулей и объёма данных в базе — не стоит выбирать объём RAM исходя из версии, ориентируйтесь на сценарий использования из таблицы выше.

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

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

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