odoo.conf et postgresql.conf générés.Tout administrateur Odoo finit par copier la même ligne depuis un forum : workers = (CPU x 2) + 1. Ce n'est pas faux, mais ce n'est que la moitié de l'histoire — et la moitié manquante est précisément ce qui remplit vos logs de MemoryError et de « too many connections ».
Le nombre de workers n'est pas un problème de CPU. C'est un problème de RAM avec un plafond CPU. Et une fois vos workers bien réglés, le goulot d'étranglement suivant est presque toujours PostgreSQL, qui tourne encore avec des valeurs par défaut de 2005 pour une charge qui n'a rien à voir avec Odoo. Ce guide traite les deux, avec les valeurs exactes, les calculs qui les justifient et les pièges que les articles de blog habituels passent sous silence.
Ce qu'est réellement un worker Odoo
En mode multiprocessing (le seul mode à utiliser en production), Odoo fork plusieurs processus système indépendants. Chacun charge l'environnement Python complet et tous les modules installés, puis garde cette mémoire résidente, même au repos. Il en existe trois types :
Ce que la plupart des guides oublient de dire clairement : les workers cron et gevent comptent eux aussi dans votre budget RAM. Si vous ne prévoyez que les workers HTTP, vous avez déjà sous-dimensionné la machine.
La formule que tout le monde cite, et ce qu'elle oublie
La règle bien connue vous donne un plafond, pas une réponse :
Deux autres règles empiriques aident à dimensionner d'après la demande plutôt que d'après le matériel :
- Un worker HTTP sert confortablement environ 6 utilisateurs simultanés (des personnes qui cliquent activement, pas seulement connectées).
- Il vous faut un minimum de 2 workers HTTP en production. La génération de PDF/rapports rappelle Odoo en HTTP via wkhtmltopdf, et avec un seul worker elle se bloque en s'attendant elle-même.
Voilà pourquoi le même « (CPU x 2) + 1 » peut être parfait sur un serveur et provoquer des OOM sur un autre. Une machine à 8 cœurs annonce « jusqu'à 17 workers », mais avec la valeur par défaut de limit_memory_soft de 2 Go, 17 workers exigeraient 34 Go de RAM pour Odoo seul.
Un odoo.conf correct, ligne par ligne
Voici un bloc prêt pour la production, avec les valeurs qui correspondent au comportement réel d'Odoo 16+. Les commentaires expliquent le rôle de chaque limite et sa vraie valeur par défaut.
Le piège des connexions dont personne ne parle
Voici celui qui casse la production en charge. Chaque worker Odoo conserve son propre pool pouvant atteindre db_maxconn connexions PostgreSQL. Le plafond réel qu'Odoo peut ouvrir est donc :
Avec les valeurs par défaut (disons 8 workers et db_maxconn = 64), cela fait plus de 500 connexions possibles, alors que PostgreSQL est livré avec max_connections = 100. Lors d'un pic de trafic, vous tombez sur FATAL: sorry, too many clients already et le site se bloque. Deux façons de corriger ça, idéalement les deux :
- Abaissez db_maxconn à 16–32 pour que le pire des cas tienne dans le max_connections de Postgres.
- Pour des parcs plus importants, placez PgBouncer en mode transaction devant Postgres et dimensionnez max_connections sur le pool, pas sur les workers.
Régler PostgreSQL pour la façon dont Odoo fonctionne
La charge d'Odoo est de type OLTP : un déluge de petites requêtes indexées générées par l'ORM et de transactions courtes, pas quelques gigantesques parcours analytiques. Cela conditionne chacune des valeurs ci-dessous. Elles supposent que Postgres dispose de la machine (ou d'une part connue de celle-ci) pour lui seul.
N'oubliez pas le reverse proxy
Les workers et Postgres sont réglés, mais si le chat en direct et les notifications « ne marchent pas », c'est presque toujours le proxy. Le trafic temps réel utilise le port gevent/longpolling (8072) et doit être routé séparément des requêtes normales (8069). Voici le nginx minimal qui fait les choses correctement.
À associer à proxy_mode = True dans odoo.conf pour qu'Odoo fasse confiance aux en-têtes transmis. Sur Odoo 16, le canal temps réel est /websocket ; les versions plus anciennes utilisaient /longpolling, gardez donc les deux par sécurité.
Exemple concret : 4 vCPU / 8 Go, Odoo + Postgres sur une seule machine
Une configuration de départ très répandue. Dimensionnons-la honnêtement, de bout en bout.
- Plafond CPU : (4 x 2) + 1 = 9 workers maximum.
- Budget RAM : 8 Go au total − ~1 Go OS − ~2 Go PostgreSQL ≈ 5 Go pour Odoo.
- Workers limités par la RAM : à limit_memory_soft = 768 MB, 5 Go / 0,77 ≈ 6 processus. Réservez-en 1 pour le cron + 1 pour gevent → ~4–5 workers HTTP.
- Le plus petit des deux gagne : 5 (RAM) < 9 (CPU) → utilisez workers = 5, max_cron_threads = 1.
- Connexions : (5 + 1 + 1) x db_maxconn 32 = 224 dans le pire des cas → réglez Postgres sur max_connections = 250, ou gardez 100 et ajoutez PgBouncer.
- Postgres : shared_buffers = 2GB, effective_cache_size = 4GB, work_mem = 16MB, maintenance_work_mem = 256MB.
Cinq workers HTTP supportent confortablement ~30 utilisateurs simultanés sur cette machine. Besoin d'en servir 60 ? Vous êtes limité par la RAM, pas par le CPU : ajoutez de la mémoire (ou déplacez Postgres sur une autre machine) avant d'ajouter des cœurs.
Passez les calculs : le calculateur de workers Odoo de DevTalents
Tout ce qui précède est intégré dans un outil gratuit. Saisissez vos cœurs CPU, votre RAM, le type de stockage et si Postgres partage la machine ; il applique le plafond de RAM, le calcul des connexions et le profil PostgreSQL OLTP, puis vous remet un odoo.conf et un postgresql.conf prêts à coller.
Workers, limites de mémoire, threads cron, db_maxconn et un profil PostgreSQL assorti. Copiez, collez, redémarrez.
Ouvrir le calculateur de workers →Vous exploitez une vraie instance de production et souhaitez un deuxième avis ? Notre équipe dimensionne et règle des déploiements Odoo au quotidien, alors contactez-nous.