Odoo 20 was released in September 2026, and our customers were not late to start posing their usual questions. Is it possible to update directly from 16? Is OpenUpgrade ready? What is the expected duration?
This guide provides initial insights into the process. It describes the basic stages and choices which have to be made in order to estimate the work volume before delving into the technicalities of the process. Based on our experience, the actual challenge in the database migration is not very common. Most of the job is related to custom modules and third-party applications.
Upgrades from 16, 17, 18 and 19
The way you can upgrade to 20 depends on your edition of Odoo. For the Odoo Enterprise version, the Odoo upgrade service can update the database to the required version in a single request no matter what the initial version is. For Odoo Community OpenUpgrade, it moves from one version to another; therefore, the number of missed versions equals additional upgrades and tests.
| Current version | Enterprise (upgrade service) | Community (OpenUpgrade) |
| Odoo 19 | One request | One run (19 to 20) |
| Odoo 18 | One request | Two runs |
| Odoo 17 | One request | Three runs |
| Odoo 16 | One request | Four runs |
However, a single migration makes the database smaller. The custom module also has to cope with all these versions, so if you have a module that was created for version 16, it will require four migrations. Also, make sure to check your server. Odoo 20 requires Python 3.12 and PostgreSQL 16 or higher, so many on-premise installations will need an update to proceed with the Odoo upgrade.
Enterprise or Community: what path do you take?
The enterprise edition users receive Odoo's upgrade service as a part of their subscription. You may order it from the Odoo Online database manager, from the Odoo.sh Upgrade tab, or for on-premise installation using the upgrade.odoo.com service or the Odoo command line tool. However, Odoo will fix issues with the upgraded standard database, but its SLA will not include in-house modules, partner modules and third-party apps. They belong to you.
Community users have an OpenUpgrade, which is an OCA's open-source upgrade project. It is free of charge, but you or your partner execute it, and all issues that are outside of its scope will require your scripts. There is a migration status for every version pair of every standard module.
Neither of them provided 20.0 as of 30 September 2026; Odoo's upgrade form and Odoo.sh only provided versions up to 19.0, and OpenUpgrade's 20.0 was still in its early stages of development (tracker ticket #6044). If you are on Community edition and are using 16 or 17 versions, there is no reason to delay. Upgrade to 19 first, and you'll have only one more step to do when OpenUpgrade 20.0 is ready.
Test upgrades on a neutralized copy
Never test an upgrade on a copy of production which can still connect to the outer world and execute scheduled tasks, email real customers, and send any data to other connected systems without someone monitoring it.
This is what neutralization will prevent. It disables outgoing mail, scheduled actions, live payment providers, and similar external connections and adds a banner to ensure no one confuses this copy with production. Databases created by Odoo's upgrade service, duplicates of the database, and staging builds from Odoo.sh are neutralized automatically. On-premise, you do it yourself:
./odoo-bin neutralize -c /etc/odoo/odoo.conf -d prod_test
Your own integrations are only covered if the module includes a data/neutralize.sql file, so add one to any custom connector. Plan for several test upgrades during the project, with a full rehearsal shortly before go-live.
User acceptance testing
A database may be upgraded flawlessly and yet cause problems for someone's working day; hence, those who use a particular process must be the ones to test it. For UAT, we divide by department, provide an owner and a limited set of critical processes per department, and reach an agreement on how the sign-off will be done prior to UAT.
In our v18 to v19 migration, when opening an email in the Chatter using the full composer, all the recipients would disappear silently. Nothing was wrong to see in the user interface, and the problem was found only after sending a test email. It is recommended to go through the upgrade report, where views that have been disabled during the upgrade will be listed.
Porting custom modules with upgrade_code
Custom modules usually take the most time. Before porting anything, compare each customization with standard Odoo 20. If v20 already does the job, remove the customization instead of porting it.
For the code you keep, Odoo 20 includes odoo-bin upgrade_code. It uses the scripts in odoo/upgrade_code/ to rewrite common changes automatically, such as tree views becoming list views, access rules moving to the new ir.access format, and OWL 2 components moving to OWL 3. Start with a dry run and limit it to your own module:
./odoo-bin upgrade_code --addons-path /opt/custom-addons \
--script 19.4-00-ir-access --glob 'my_module/**/*' --dry-run
These scripts handle syntax. Business logic, view inheritance that targets changed elements and data migration still need a developer, and renamed fields or models need their own migration scripts.
Check third-party app availability
Before setting the go-live date, compile a list of all non-standard modules by their source, their owner, and the availability of a v20 version. Make sure to check the Odoo Apps Store for 20.0 versions and OCA repositories for 20.0 branches. At the early stage of a release cycle, there will probably be a few blanks here and there.
For each of these modules, determine whether you should wait for it to be ported, find an alternative, port the module on your own, or simply remove it from the system. Some functionality is integrated in the standard Odoo 20 (for instance, batch transfers are already a part of the Inventory), and finding an alternative may not seem like such a big deal.
Cutover and rollback plan
Write the cutover down step by step and rehearse it on production-sized data, timing each step. Freeze data entry during the cutover, because anything entered after the final backup won't be in the upgraded database. A typical sequence looks like this:
- Announce the downtime and the data-entry freeze.
- Pause integrations and stop Odoo.
- Back up the database and filestore, and check that the backup restores.
- Run the production upgrade and deploy your ported modules.
- Smoke test the key processes and compare figures such as the trial balance and stock value with production.
- Make the go or no-go decision against conditions you agreed on in advance.
Keep the old server untouched until v20 has been running smoothly for a while. If the upgrade fails, rolling back means pointing users back to the old system and restoring the backup. Set a hard deadline for that decision. Once people start working in v20, a rollback would lose their transactions, so from that point you fix forward. On Odoo Online, a finished production upgrade can't be reverted.
These ranges come from typical projects. The biggest factors are the number and quality of your custom modules, how many versions you're jumping, and whether your third-party apps are ready.
| Phase | Little customization | Moderate (5 to 20 custom or third-party modules) | Heavy customization or multi-company |
| Analysis and inventory | 2 to 5 days | 1 to 2 weeks | 2 to 4 weeks |
| Test upgrades | 1 to 3 days | 1 to 2 weeks | 2 to 6 weeks |
| Porting custom modules | 0 to 3 days | 2 to 6 weeks | 2 to 4 months or more |
| UAT | 1 week | 2 to 3 weeks | 4 to 8 weeks |
| Cutover | A day or a weekend | One weekend | One or two weekends, plus a rehearsal |
| Typical total | 2 to 4 weeks | 1.5 to 3 months | 3 to 6 months or more |
Add extra time for each additional OpenUpgrade run and for any server upgrades to Python 3.12 or PostgreSQL 16.
The best way to plan an upgrade is through an inventory of your existing modules, customizations, and integrations. After getting your information, the path to take will be easier to choose, and time estimates made will be more realistic.
Do you plan on upgrading your Odoo 20 system yourself? Let Cybrosys audit your system and come up with a migration plan.
To read more about How to Migrate Custom Modules from Odoo 18 to Odoo 19, refer to our blog How to Migrate Custom Modules from Odoo 18 to Odoo 19.