Odoo Server Sizing Calculator
Stop guessing. Calculate the exact CPU, RAM, and Worker configurations for high-concurrency Odoo clusters.
Input Parameters
Enter user count to see specs
Recommended Config
Production ReadyUnderstanding Odoo Hardware Requirements
How Odoo Workers Are Calculated
Each Odoo worker is a Python process that handles exactly one HTTP request at a time. The
concurrency rule of thumb — 1 worker per 6 concurrent users — assumes typical interactive
behavior: users are reading screens, typing, and thinking between clicks. Only about 1 in 6
users is actually waiting for a server response at any given second.
For heavy workloads (batch MRP, eCommerce with checkout flows, external API integrations),
this ratio tightens to 1:4 because more requests are long-running and keep workers occupied.
Odoo always spawns one additional cron worker beyond the HTTP worker count.
The hardware must be sized for all processes, not just HTTP workers.
Why Most RAM Estimates Are Too Low
The most common mistake is estimating RAM only for Odoo workers and ignoring PostgreSQL.
On a typical Odoo server running both services, the database layer needs at least
25–40% of total RAM for shared_buffers and working memory — entirely
separate from what Odoo workers consume.
Odoo workers themselves are heavier than most documentation suggests. A loaded worker
with common modules (Sales, Inventory, Accounting) sits at 400–500 MB resident
memory — before serving any request. Heavy modules (MRP, eCommerce) push this
to 700–900 MB.
The limit_memory_soft setting tells Odoo to recycle a worker gracefully
once it crosses the threshold. Set this too low and workers recycle constantly,
degrading performance. Set it too high and a runaway request can exhaust all available RAM.
PostgreSQL Tuning Parameters
shared_buffers is the most impactful single change you can make to
PostgreSQL performance. The default (128 MB) is designed for minimal systems.
Setting it to 25% of system RAM means frequently accessed tables — Partners, Products,
Sale Orders — stay cached in RAM instead of being read from disk on every query.
work_mem controls memory allocated per sort or hash operation. Odoo
generates complex queries involving multiple sorts. Too low and PostgreSQL spills
to disk; too high and it multiplies across concurrent connections (a 16 MB setting
with 50 connections could use 800 MB on a single complex query).
max_connections should match your actual connection needs — Odoo workers
maintain persistent database connections. If your worker count pushes max_connections
above 100, use PgBouncer in transaction mode to pool connections rather
than increasing max_connections further, which wastes shared memory.
Common Sizing Mistakes
- Sizing for registered users, not concurrent users. A company with 200 employees typically has 20–40 concurrent Odoo users during peak hours.
- Forgetting the cron worker. Odoo always adds 1 cron process. On a 2-CPU server with 4 HTTP workers, the 5th process is constantly competing for CPU.
- Using PostgreSQL defaults. A fresh PostgreSQL install has shared_buffers = 128 MB. On a 16 GB server this leaves 15.9 GB unused by the database cache.
- Under-provisioning for custom modules. Each custom module adds Python objects to every worker's memory. 10 small modules can add 200–400 MB per worker.
- Ignoring I/O. Even with correctly sized RAM, slow disk (spinning HDD, network storage) will bottleneck PostgreSQL. Use NVMe SSDs for the data directory.
Need a deeper system review?
This calculator gives you the right starting point. A full Odoo Performance Audit goes further — we run pg_stat_statements analysis against your live database, review your actual worker memory consumption, and check your custom module code for N+1 queries and compute field inefficiencies that no sizing formula can predict.