Whether you stay on Community, run Enterprise, or mix hosted and self-managed pieces, the upgrade problem is the same: your database carries history, and Odoo's core moves forward every year. Security work and backups still matter on the version you run today (see securing an Odoo instance). This article is about crossing to the next version without betting the company on a single untested afternoon.
Why Odoo upgrades hurt
Odoo is not a static app with a plugin folder. It is an ERP kernel, dozens of official apps, optional OCA or commercial modules, and often custom Python, XML, and JavaScript that patched a gap years ago.
- Schema and ORM changes. Field renames, model merges, and new constraints break inherited views and automated actions silently until someone opens a screen.
- Custom code debt. Overrides that worked on Odoo 14 may import removed utilities on 17. Unmaintained modules block the whole jump.
- Third-party lag. A payment connector or shipping label app may not publish a compatible branch for months. You cannot upgrade until they do, or you replace them.
- Data you forgot about. Old demo companies, duplicate products, broken BOMs, and half-finished migrations surface during upgrade scripts and fail the process.
- Integrations off the UI. Warehouse scanners, EDI, marketplace sync, and payroll exports often call RPC, webhooks, or SQL outside Odoo's upgrade wizard. They do not upgrade themselves.
- Edition boundaries. Community vs Enterprise features and licensing change what you can install and who supports the migration path (see Odoo Community vs Enterprise).
- Operational coupling. Month-end close, peak season, or a go-live elsewhere on the stack is the wrong week to learn that manufacturing routes no longer compute.
Pain is not proof that Odoo failed. It is proof that your instance became a system of record with real complexity. The goal is to make that complexity visible before production stops.
What drives cost and duration
Integrators quote upgrades from a few days to several months. The spread usually comes from these drivers, not from the version number alone.
- Number of custom and third-party modules and whether source code and tests exist
- Gap between versions. Skipping releases (for example 13 to 17) costs more than stepping through supported paths
- Quality of the module inventory. Unknown apps installed years ago need discovery time (see evaluating open source project health for maintainer risk on dependencies you rely on)
- Volume and cleanliness of data. Millions of stock moves or unreconciled bank lines slow migration and testing
- Integrations count. Each external system needs a regression plan (see five ways two-system sync fails)
- Reporting and documents. QWeb templates, spreadsheets, and studio customizations break in subtle ways
- Who runs the project. A clear internal owner and a vendor with Odoo migration experience beat an email thread with five CCs
- Staging realism. A toy database proves little. A copy with representative data and the same modules proves a lot (see staging environment done right)
- Contract scope. Fixed price without a module list often ends in change requests (see what maintenance contracts should include and clauses for tech contractors)
Cleaning before you move is cheaper than debugging on production. So is retiring a bad module choice early (see Odoo vs bespoke software when the ERP was the wrong hammer).
Step 1: Name an owner and freeze scope
Pick one person who can say no to new modules until cutover. Upgrades fail when sales asks for a new app mid-migration or when finance changes chart of accounts during rehearsal.
- Write the target version, desired window, and success criteria (for example "warehouse ships on Monday", "accounting closes February")
- List stakeholders: operations, accounting, IT, integrator, hosting
- Agree what is out of scope for this jump (new website, payment provider switch) unless you budget extra time
- Collect existing runbooks and access lists. If none exist, ask for them at delivery next time (see documentation to require at handover)
Step 2: Baseline the current stack
- Exact Odoo version, edition, and hosting model (Odoo.sh, partner server, your VPS)
- Python, PostgreSQL, and OS versions. End-of-life components may force infrastructure work before Odoo moves
- Full list of installed modules with version numbers and source (official, OCA, commercial, custom)
- Custom addons path, Git remotes, and who can merge to production
- Reverse proxy, workers, cron schedule, and outbound mail setup
- Backup and restore procedure that includes filestore (see backups that actually restore)
You cannot estimate effort on a database nobody has inventoried since go-live.
Step 3: Audit modules and customizations
Every installed app is a migration work item.
- Mark each module: keep, replace, uninstall before upgrade, or rewrite
- Read release notes for deprecated models and removed wizards on your target version
- Trace custom code: inherited models, cron jobs, server actions, automated emails, portal controllers
- Flag modules with no maintainer, unclear licence, or last commit older than two years
- For retail and stock-heavy setups, list barcode, POS, and delivery flows explicitly (see Odoo shop and stock pitfalls)
- Check whether Enterprise-only modules tie you to Odoo SA's upgrade service or a partner pipeline
If an audit reveals the integrator never documented what they built, treat that as a red flag for the next contract (see warning signs with a freelance developer).
Step 4: Clean data and retire dead features
Upgrade scripts assume coherent data. Garbage in becomes failed migrations and mysterious tracebacks.
- Uninstall unused apps properly after exporting anything you need
- Archive obsolete products, partners, and journals instead of leaving duplicates active
- Fix known broken records: negative stock without rules, invoices stuck in draft, BOMs with zero components
- Remove test companies and demo databases from production URLs
- Align units of measure, taxes, and fiscal positions before the jump so accounting tests mean something
Cleanup on production is delicate. Do it on a copy first, script what works, then repeat on live during a maintenance window.
Step 5: Map integrations and scheduled jobs
- Inventory APIs, XML-RPC, CSV exports, ETL jobs, and middleware that read or write Odoo
- Note authentication method and whether credentials rotate on upgrade
- List crons and queue jobs with business impact if they stop for an hour
- Document idempotency expectations for money flows (see idempotence explained with two invoices)
- Plan parallel runs or read-only mode for systems that cannot tolerate half-upgraded schemas
Integrations cause more production surprises than standard Odoo screens. Give them their own test checklist.
Stuck several versions behind?
Share your module list, hosting, and target version. We can help you sequence cleanup, staging, and cutover without treating the upgrade as a black box.
Step 6: Build staging that matches production
- Restore a recent backup to an isolated environment with the same module set and similar worker config
- Use anonymized data where personal records would violate policy (see GDPR and test environments)
- Point staging integrations at sandboxes, not live payment or carrier accounts
- Restrict staging URLs by VPN or IP. A public clone of production is a security incident waiting to happen
- Keep staging refreshed after major data or config changes on production
A staging environment done right is the cheapest place to fail (see staging environment done right).
Step 7: Rehearse the upgrade on disposable copies
- Run the full migration path on a throwaway database until it completes without manual hacks
- Time each phase: backup, file copy, Odoo upgrade, module updates, post-init scripts
- Capture logs and document every manual step. Your production runbook is this rehearsal plus rollback
- Repeat after fixing blockers. First success is not enough if it took three days of developer intervention
- If you change hosting at the same time, rehearse DNS and mail separately (see changing host without interruption and migrating DNS without breaking email)
Rehearsal is where you discover that one OCA module needs a fork or that PostgreSQL must jump first.
Step 8: Test critical flows and integrations
Define scenarios with real users, not only IT clicking menus.
- Sales to delivery to invoice, including returns and credit notes
- Purchase approval, receipt, and vendor bill matching
- Manufacturing or subcontracting if you use it
- Bank reconciliation and tax reports for your jurisdiction
- Portal orders, helpdesk tickets, or subscription billing if customers touch Odoo
- Each integration: create, update, cancel, and error paths
- Printed PDFs and email templates finance sends externally
Compare key balances and open items between old and new staging copies where possible. Surprises at month-end are expensive.
Step 9: Cut over, rollback, and plan the next jump
- Choose a window with slack, communicate freeze on master data changes, and disable crons that push offsite during migration
- Take a fresh backup immediately before cutover. Verify restore once more if the gap since last test was long
- Run the rehearsed steps with a written go/no-go checklist and a named rollback decision maker
- Rollback plan: restore previous database and filestore, revert DNS, re-enable integrations, and communicate clearly if you abort
- After go-live, monitor logs, queue depth, integration error rates, and user-reported blockers for at least one full business cycle
- Update internal docs: new version, module changes, integration endpoints, and lessons for the next upgrade
- Schedule minor updates and security patches so the next major jump is not another multi-year leap
Leaving Odoo SaaS for self-hosted or the reverse adds exit steps (see leaving SaaS without losing data). Payment lock-in can complicate module swaps mid-upgrade (see payment provider lock-in).
Questions to ask integrators and hosts
- Which exact source and target versions have you migrated in production in the last twelve months?
- Do you upgrade Community, Enterprise, or both, and who handles Odoo SA subscription steps if applicable?
- How do you price: fixed scope with module list, time and materials, or hybrid?
- What is included: custom code fixes, third-party module updates, data repair, training, hypercare?
- How many full dress rehearsals on our copy before production cutover?
- Who owns rollback if go-live fails at hour six?
- Will we get Git access, migration logs, and an updated module inventory in our repo?
- How do you handle integrations we operate ourselves?
- What is the plan for PostgreSQL or OS upgrades if they block Odoo?
- References from a customer with similar modules and data volume?
Vague answers on rehearsal count and rollback usually predict vague delivery.
Common mistakes
- Upgrading production first because "staging costs too much"
- Assuming Odoo.sh or a host "handles everything" without a module compatibility review
- Installing new customizations during the migration month
- Skipping filestore backup or restore test before the jump
- Treating third-party modules as zero effort because they are "just from the store"
- No communication freeze on pricing, products, or chart of accounts during cutover
- Integrations tested only after users report failures
- Letting the integrator own the only copy of fixed custom code
- Waiting five years between major versions then blaming Odoo for the size of the bill
- No rollback decision maker when fatigue sets in at 2 a.m.
Checklist
- Internal owner named, scope frozen, target version and window agreed
- Full module and custom code inventory with keep/replace/uninstall decisions
- Data cleanup rehearsed on a copy, known bad records fixed or archived
- Integrations and crons documented with sandbox test plan
- Staging environment mirrors production modules and realistic data
- End-to-end upgrade succeeded at least twice on disposable databases with timed runbook
- Business and integration test scripts signed off by process owners
- Pre-cutover backup and filestore restore verified
- Written rollback plan, go/no-go criteria, and communication to users
- Post-go-live monitoring and updated documentation for the next jump
Want a migration-shaped upgrade plan?
Tell us your current version, module list, and integrations. We will help you prioritize cleanup, rehearsal, and cutover.
Community, Enterprise ou mix hébergé, le problème d'upgrade est le même: votre base porte l'historique, et le cœur Odoo avance chaque année. Sécurité et sauvegardes restent indispensables sur la version actuelle (voir sécuriser une instance Odoo). Cet article parle de passer à la version suivante sans parier l'activité sur un seul après-midi non testé.
Pourquoi les upgrades Odoo font mal
Odoo n'est pas une application figée avec un dossier de plugins. C'est un noyau ERP, des dizaines d'apps officielles, des modules OCA ou commerciaux optionnels, et souvent du Python, XML ou JavaScript sur mesure qui comblait un trou il y a des années.
- Schéma et ORM. Renommages de champs, fusions de modèles et nouvelles contraintes cassent vues héritées et actions automatisées jusqu'à ce qu'un écran s'ouvre.
- Dette de code sur mesure. Des surcharges valides en Odoo 14 importent des utilitaires supprimés en 17. Un module non maintenu bloque tout le saut.
- Retard des tiers. Un connecteur paiement ou étiquette transport peut ne publier une branche compatible qu'après des mois. Vous n'avancez pas tant que vous ne remplacez pas.
- Données oubliées. Anciennes sociétés démo, produits dupliqués, nomenclatures cassées et migrations à moitié finies remontent pendant les scripts d'upgrade et font échouer la migration.
- Intégrations hors interface. Scanners entrepôt, EDI, sync marketplace et exports paie appellent souvent RPC, webhooks ou SQL en dehors de l'assistant Odoo. Elles ne se mettent pas à jour seules.
- Frontières d'édition. Community et Enterprise changent ce que vous installez et qui porte le chemin de migration (voir Odoo Community vs Enterprise).
- Couplage opérationnel. Clôture mensuelle, pic saisonnier ou go-live ailleurs dans la stack est la mauvaise semaine pour découvrir que les routes de fabrication ne calculent plus.
La douleur ne prouve pas qu'Odoo a échoué. Elle prouve que votre instance est devenue un système de référence avec une vraie complexité. Le but est de rendre cette complexité visible avant l'arrêt de la production.
Ce qui fait monter coût et durée
Les intégrateurs chiffrent de quelques jours à plusieurs mois. L'écart vient surtout de ces leviers, pas du numéro de version seul.
- Nombre de modules sur mesure et tiers et existence de code source et tests
- Écart entre versions. Sauter des releases (par exemple 13 vers 17) coûte plus qu'un chemin supporté pas à pas
- Qualité de l'inventaire modules. Des apps installées sans trace demandent du temps de découverte (voir évaluer la santé d'un projet open source pour le risque mainteneur)
- Volume et propreté des données. Millions de mouvements de stock ou lignes bancaires non rapprochées ralentissent migration et tests
- Nombre d'intégrations. Chaque système externe exige un plan de régression (voir cinq pannes typiques de sync entre deux systèmes)
- Reporting et documents. Modèles QWeb, tableurs et personnalisations Studio cassent de façon subtile
- Qui pilote. Un responsable interne clair et un prestataire habitué aux migrations Odoo valent mieux qu'un fil de mails à cinq copies
- Réalisme du staging. Une base jouet prouve peu. Une copie représentative avec les mêmes modules en dit long (voir environnement de staging bien fait)
- Périmètre contractuel. Forfait sans liste de modules mène souvent aux avenants (voir contrats de maintenance: ce qui doit être inclus et clauses contrat prestataire tech)
Nettoyer avant de bouger coûte moins que déboguer en production. Retirer tôt un mauvais choix de module aussi (voir Odoo ou logiciel sur mesure quand l'ERP était le mau marteau).
Étape 1: Nommer un responsable et geler le périmètre
Désignez une personne capable de dire non aux nouveaux modules jusqu'à la bascule. L'upgrade échoue quand les ventes demandent une app en pleine migration ou que la compta change le plan comptable pendant la répétition.
- Écrire version cible, fenêtre souhaitée et critères de succès (par exemple « l'entrepôt expédie lundi », « clôture février OK »)
- Lister les parties prenantes: ops, compta, IT, intégrateur, hébergeur
- Accorder sur ce qui est hors scope pour ce saut (nouveau site, changement prestataire paiement) sauf budget supplémentaire
- Rassembler runbooks et listes d'accès existants. S'il n'y en a pas, exigez-les à la prochaine livraison (voir documentation à exiger à la livraison)
Étape 2: Poser la photo de la stack actuelle
- Version Odoo exacte, édition et mode d'hébergement (Odoo.sh, serveur partenaire, votre VPS)
- Versions Python, PostgreSQL et OS. Des composants en fin de vie imposent parfois l'infra avant Odoo
- Liste complète des modules installés avec numéros de version et source (officiel, OCA, commercial, sur mesure)
- Chemin addons sur mesure, remotes Git et qui peut merger en production
- Reverse proxy, workers, crons et envoi mail sortant
- Procédure de sauvegarde et restauration incluant le filestore (voir des sauvegardes qui restaurent vraiment)
On ne chiffre pas l'effort sur une base que personne n'a inventoriée depuis le go-live.
Étape 3: Auditer modules et personnalisations
Chaque app installée est un poste de migration.
- Marquer chaque module: garder, remplacer, désinstaller avant upgrade, ou réécrire
- Lire les notes de version sur modèles dépréciés et assistants supprimés sur la cible
- Tracer le sur mesure: modèles hérités, crons, actions serveur, mails auto, contrôleurs portail
- Signaler modules sans mainteneur, licence floue ou dernier commit vieux de plus de deux ans
- Pour boutique et stock, lister explicitement codes-barres, POS et flux livraison (voir boutique Odoo et pièges stock)
- Vérifier si des modules Enterprise seuls vous lient au service upgrade Odoo SA ou à un pipeline partenaire
Si l'audit montre que l'intégrateur n'a jamais documenté ce qu'il a construit, traitez cela comme signal pour le prochain contrat (voir signaux d'alerte avec un freelance développeur).
Étape 4: Nettoyer les données et retirer le mort
Les scripts d'upgrade supposent des données cohérentes. Les entrées poubelle deviennent migrations échouées et tracebacks obscurs.
- Désinstaller proprement les apps inutilisées après export de ce qu'il faut garder
- Archiver produits, partenaires et journaux obsolètes au lieu de laisser des doublons actifs
- Corriger les enregistrements connus comme cassés: stock négatif sans règle, factures bloquées en brouillon, nomenclatures sans composant
- Retirer sociétés test et bases démo des URL de production
- Aligner unités, taxes et positions fiscales avant le saut pour que les tests compta aient du sens
Le nettoyage en production est délicat. Faites-le sur copie, scriptez ce qui marche, puis reproduisez en live dans une fenêtre de maintenance.
Étape 5: Cartographier intégrations et jobs planifiés
- Inventorier API, XML-RPC, exports CSV, ETL et middleware qui lisent ou écrivent Odoo
- Noter l'authentification et si les identifiants changent à l'upgrade
- Lister crons et files de jobs avec impact métier s'ils s'arrêtent une heure
- Documenter l'idempotence attendue sur les flux d'argent (voir idempotence expliquée avec deux factures)
- Prévoir exécutions parallèles ou mode lecture seule pour les systèmes qui tolèrent mal un schéma à moitié migré
Les intégrations provoquent plus de surprises en production que les écrans Odoo standard. Donnez-leur leur propre checklist de test.
Coincé à plusieurs versions de retard ?
Partagez liste de modules, hébergement et version cible. On peut vous aider à enchaîner nettoyage, staging et bascule sans traiter l'upgrade comme une boîte noire.
Étape 6: Construire un staging calqué sur la production
- Restaurer une sauvegarde récente dans un environnement isolé avec le même jeu de modules et une config workers proche
- Anonymiser où des données personnelles violeraient la politique (voir RGPD et environnements de test)
- Pointer les intégrations staging vers des bacs à sable, pas vers paiement ou transporteur live
- Restreindre les URL staging par VPN ou IP. Un clone public de production attend un incident sécurité
- Rafraîchir le staging après changements majeurs de données ou config en production
Un staging bien fait est l'endroit le moins cher pour échouer (voir environnement de staging bien fait).
Étape 7: Répéter l'upgrade sur des copies jetables
- Exécuter tout le chemin de migration sur une base sacrifiable jusqu'à complétion sans bricolage manuel
- Chronométrer chaque phase: sauvegarde, copie fichiers, upgrade Odoo, mises à jour modules, scripts post-init
- Capturer les logs et documenter chaque étape manuelle. Le runbook production, c'est cette répétition plus le rollback
- Recommencer après chaque bloquant. Un premier succès ne suffit pas s'il a demandé trois jours d'intervention dev
- Si vous changez d'hébergeur en même temps, répéter DNS et mail à part (voir changer d'hébergeur sans interruption et migrer le DNS sans casser l'email)
C'est en répétition qu'on découvre le module OCA à forker ou PostgreSQL à monter avant Odoo.
Étape 8: Tester flux critiques et intégrations
Définissez des scénarios avec des utilisateurs métier, pas seulement l'IT qui clique dans les menus.
- Vente à livraison à facture, retours et avoirs inclus
- Validation achat, réception et rapprochement facture fournisseur
- Fabrication ou sous-traitance si vous les utilisez
- Rapprochement bancaire et déclarations fiscales pour votre pays
- Commandes portail, tickets helpdesk ou abonnements si les clients touchent Odoo
- Chaque intégration: création, mise à jour, annulation et chemins d'erreur
- PDF imprimés et modèles de mail que la compta envoie à l'extérieur
Comparez soldes et encours entre ancienne et nouvelle copie staging quand c'est possible. Les surprises en clôture coûtent cher.
Étape 9: Basculer, rollback et préparer le prochain saut
- Choisir une fenêtre avec marge, communiquer le gel des changements sur données de référence, désactiver les crons qui poussent hors Odoo pendant la migration
- Sauvegarde fraîche juste avant bascule. Revérifier la restauration si le dernier test date
- Exécuter les étapes répétées avec checklist go/no-go écrite et décideur rollback nommé
- Plan rollback: restaurer base et filestore précédents, revenir DNS, réactiver intégrations, communiquer clairement si vous abandonnez
- Après go-live, surveiller logs, profondeur de files, taux d'erreur intégrations et blocages remontés par les utilisateurs sur au moins un cycle métier complet
- Mettre à jour la doc interne: nouvelle version, changements modules, endpoints intégrations et leçons pour le prochain upgrade
- Planifier correctifs mineurs et sécurité pour que le prochain saut majeur ne soit pas un écart de plusieurs années
Quitter le SaaS Odoo pour de l'auto-hébergé ou l'inverse ajoute des étapes de sortie (voir sortir du SaaS sans perdre vos données). Le lock-in paiement complique les swaps de module en plein upgrade (voir lock-in prestataire paiement).
Questions à poser aux intégrateurs et hébergeurs
- Quelles versions source et cible exactes avez-vous migrées en production ces douze derniers mois ?
- Upgrade Community, Enterprise ou les deux, et qui gère les étapes abonnement Odoo SA le cas échéant ?
- Comment chiffrez-vous: forfait avec liste modules, régie, ou mix ?
- Qu'inclut le prix: correctifs sur mesure, mises à jour modules tiers, réparation données, formation, hypercare ?
- Combien de répétitions complètes sur notre copie avant bascule production ?
- Qui porte le rollback si le go-live échoue à la sixième heure ?
- Aurons-nous accès Git, logs de migration et inventaire modules à jour dans notre dépôt ?
- Comment traitez-vous les intégrations que nous opérons nous-mêmes ?
- Quel plan si PostgreSQL ou l'OS bloquent Odoo ?
- Références client avec modules et volume de données comparables ?
Des réponses vagues sur le nombre de répétitions et le rollback annoncent souvent une livraison vague.
Erreurs fréquentes
- Upgrader la production d'abord parce que « le staging coûte trop cher »
- Supposer qu'Odoo.sh ou l'hébergeur « gère tout » sans revue compatibilité modules
- Installer du sur mesure pendant le mois de migration
- Oublier sauvegarde filestore ou test de restauration avant le saut
- Traiter les modules tiers comme effort zéro parce qu'ils viennent « juste du store »
- Aucun gel communiqué sur tarifs, produits ou plan comptable pendant la bascule
- Intégrations testées seulement après signalement utilisateur
- Laisser l'intégrateur seul détenteur du code corrigé
- Attendre cinq ans entre sauts majeurs puis reprocher à Odoo la taille de la facture
- Pas de décideur rollback quand la fatigue arrive à 2 h du matin
Checklist
- Responsable interne nommé, périmètre gelé, version cible et fenêtre accordées
- Inventaire complet modules et code sur mesure avec décisions garder/remplacer/désinstaller
- Nettoyage données répété sur copie, enregistrements cassés connus corrigés ou archivés
- Intégrations et crons documentés avec plan de test bac à sable
- Staging calqué sur modules production et données réalistes
- Upgrade bout en bout réussi au moins deux fois sur bases jetables avec runbook chronométré
- Scénarios métier et intégrations validés par les responsables process
- Sauvegarde pré-bascule et restauration filestore vérifiées
- Plan rollback écrit, critères go/no-go et communication utilisateurs
- Surveillance post-go-live et documentation à jour pour le prochain saut
Vous voulez un plan d'upgrade en forme de migration ?
Indiquez version actuelle, liste de modules et intégrations. On vous aide à prioriser nettoyage, répétition et bascule.