The Memory Problem
Your D2C server has 16GB RAM. Staff says "Odoo slows down under load." You check:
Workers: 1 (single-threaded, only uses 1 CPU core)
Memory per worker: 13GB (way too much, only 3GB for database)
Swap active: Continuously swapping to disk (super slow)
Database connections: Maxed out
Result: System crawls when 20+ staff members log in
With Proper Tuning
Workers: 9 (uses all 4 cores efficiently)
Memory per worker: 1.2GB (sustainable per worker)
Swap: Minimal (only emergency)
Database connections: 40 (supports 100+ concurrent users)
Result: Handles 100+ concurrent users smoothly
The Difference: Unusable vs. blazing fast.
Zero code changes.
We've implemented 150+ Odoo systems. The ones with proper memory tuning? Lightning-fast under load, happy staff, zero crashes. The ones with default settings? Performance degrades the moment you add more users, staff complains, company buys emergency hardware that doesn't help. That's $50,000-$150,000 in wasted infrastructure and consulting.
Understanding Memory in Odoo (The Architecture)
Memory is Used By
Total Server RAM (16GB)
├── Odoo Workers (9 workers × 1.2GB) = 10.8GB
├── PostgreSQL (3GB for buffers/cache)
├── System OS (1.2GB)
└── Free/Cache (1GB emergency buffer)
Workers are Separate Processes
Each worker can handle 6-8 concurrent users
For 100 concurrent users: Need 100 / 7 ≈ 15 workers
But also limited by CPU cores
Memory Leak Protection
Worker allocated: 1.2GB
Worker uses: 1.5GB (memory leak or heavy request)
limit_memory_soft: 1.2GB → Worker restarts after current request
limit_memory_hard: 1.5GB → Worker killed immediately
Without limits: Memory grows until OOM killer crashes system
The Perfect Odoo Configuration Formula
Step 1: Calculate Number of Workers
Workers = (CPU Cores × 2) + 1
Examples:
- 2 cores → 5 workers
- 4 cores → 9 workers
- 8 cores → 17 workers
Constraint: Don't exceed (Total RAM / 1.5GB per worker)
If 16GB RAM: 16 / 1.5 ≈ 10 workers max
If formula gives 17 workers, use 10 instead
Step 2: Calculate Memory Limits
Available RAM for Odoo = Total RAM - PostgreSQL - OS - Buffer
For 16GB server:
16GB (total) - 3GB (PostgreSQL) - 1.2GB (OS) = 11.8GB for Odoo
limit_memory_hard = Available RAM / Workers
limit_memory_soft = 0.75 × limit_memory_hard
If 9 workers:
limit_memory_hard = 11.8GB / 9 ≈ 1,310MB
limit_memory_soft = 0.75 × 1,310MB ≈ 983MB
Step 3: Configure odoo.conf
[options]
workers = 9
limit_memory_soft = 983
limit_memory_hard = 1310
# Cron jobs need CPU (don't max out workers with cron)
max_cron_threads = 2
# Database connections
db_maxconn = (workers × 2) + 10
# If workers=9: db_maxconn = 28
# Request timeouts
limit_time_real = 120 # 2 minutes max per request
limit_time_cpu = 60 # 1 minute CPU time
limit_request = 8192 # Max requests per worker before restart
Real D2C Example Configuration
Server Specs
| Component | Allocation |
|---|---|
| CPU | 8 cores |
| RAM | 32GB |
| PostgreSQL | 6GB dedicated |
| OS | 2GB |
| Available for Odoo | 24GB |
Calculate Workers
Formula: (8 × 2) + 1 = 17 workers
Max by RAM: 24GB / 1.2GB = 20 workers
Use: 17 workers
Memory Per Worker
limit_memory_hard = 24GB / 17 ≈ 1,411MB
limit_memory_soft = 0.75 × 1,411 ≈ 1,058MB
Configuration
[options]
; Listening
host = 0.0.0.0
port = 8069
; Database
db_host = localhost
db_user = odoo
db_password = password
db_maxconn = 44 # (17 × 2) + 10
; Workers & Memory
workers = 17
limit_memory_soft = 1058
limit_memory_hard = 1411
limit_time_real = 120
limit_time_cpu = 60
limit_request = 8192
; Cron jobs
max_cron_threads = 2
; Other
logfile = /var/log/odoo/odoo.log
log_level = info
Result
Handles 17 × 7 ≈ 119 concurrent users
Memory stable (workers recycle at 1GB)
No OOM crashes
CPU efficiently used
Linux Kernel Tuning (System Level)
For optimal memory usage:
# Swappiness (how often to use swap)
# 0-10: Minimal swap (use for servers with enough RAM)
# 60-100: Use swap freely (for systems with limited RAM)
vm.swappiness = 10
# Cache pressure (when to reclaim cache)
# 50: Default (good balance)
# 100: Aggressive reclaim (for tight memory)
vm.vfs_cache_pressure = 50
# Overcommit memory (allow RAM overallocation)
# 0: Conservative (recommended for Odoo)
# 1: Allow overcommit
vm.overcommit_memory = 0
# Apply changes
sudo sysctl -p
Verify Settings
# Check current settings
sysctl vm.swappiness
sysctl vm.vfs_cache_pressure
# Check memory usage
free -h
# Check swap usage
swapon --show
Add Swap (If Needed)
# For 32GB server, 4GB swap is good emergency buffer
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Monitoring Memory (Ongoing)
Monitor Worker Memory Usage
# Check each worker's memory
ps aux | grep odoo | grep worker
# Output:
# odoo 1234 5.2 12.1 2834568 3984432 worker 0
# odoo 1235 4.8 11.9 2814456 3904256 worker 1
# Column 4: % of RAM
# Column 6: Memory in KB
# Worker 0: 12.1% of 32GB ≈ 3.9GB (too high!)
# Should be < 5% (1.6GB)
Find Memory Leaks
# /etc/odoo/odoo.conf
log_level = debug
# Check logs for patterns
tail -f /var/log/odoo/odoo.log | grep "memory"
Automated Monitoring
#!/bin/bash
THRESHOLD=80 # Alert if RAM > 80% used
USAGE=$(free | grep Mem | awk '{print ($3/$2) * 100}')
if (( $(echo "$USAGE > $THRESHOLD" | bc -l) )); then
echo "WARNING: Memory usage at ${USAGE}%" | mail -s "Odoo Memory Alert" admin@example.com
fi
# Add to crontab to run every 5 minutes
# */5 * * * * /usr/local/bin/check_memory.sh
Your Action Items
Immediate (30 minutes)
❏ Check current worker count: ps aux | grep worker | wc -l
❏ Check current memory limits: grep limit_memory /etc/odoo/odoo.conf
❏ Check free RAM: free -h
❏ Calculate optimal configuration (use formula above)
Short-term (1 hour)
❏ Update odoo.conf with optimal settings
❏ Update Linux kernel parameters (sysctl)
❏ Add swap space if needed
❏ Restart Odoo
Test
❏ Have 20+ staff members log in simultaneously
❏ Monitor memory: watch free -h
❏ Check worker restarts: tail -f /var/log/odoo/odoo.log | grep restart
❏ Verify no slowdowns
Ongoing
❏ Weekly memory monitoring
❏ Alert if swap > 100MB (sign of memory pressure)
❏ Adjust workers if staff grows
Free Server Configuration Workshop
Stop guessing about memory settings. Most D2C brands are running Odoo with default settings, limiting them to 10% of their server capacity. Proper tuning costs 2-4 hours, delivers 10x better performance. We'll analyze your current configuration, calculate optimal worker/memory settings, configure Linux kernel parameters, set up monitoring, and test under load.
