To upgrade to Odoo 20: freeze new developments, request an upgraded test database from Odoo, port your custom modules, test your daily flows on the test copy, reconcile it against the live system, rehearse, then upgrade production in a quiet window. The steps are the same on Odoo Online, Odoo.sh and your own server; only the buttons differ. What follows is the order we use, with Odoo’s documented process and the Odoo 20 changes that catch companies out.
Before you start: what an upgrade covers
- You can upgrade from any version to any major version still in standard support, so a database on Odoo 16 or 17 can go straight to Odoo 20.
- An upgrade does not switch editions, change hosting, go back to an older version or bring data in from another ERP. Each of those is a separate project.
- With Odoo Enterprise, the upgrade of standard apps and of Studio customizations is free, with Odoo’s support for issues in the upgraded database. Custom modules are the maintainer’s job unless they are under a maintenance of customizations subscription.
- On Odoo Online a major version must be upgraded every two years. On Odoo.sh you get two more years after the three years of standard support, with extended support at an extra fee.
Step 1: freeze developments and take stock
Odoo recommends stopping new development while the upgrade runs, except bug fixes, because every change would have to be upgraded and tested again. Use the pause to list what you have:
- Installed apps and the number of companies in the database.
- Custom modules, who wrote them and who maintains them now.
- Studio changes, Arabic report layouts and email templates.
- Integrations: payment gateways, online stores, banks, shipping, and anything that calls Odoo’s API.
- Scheduled actions, automations, printers and IoT boxes.
Then compare each custom module with the Odoo 20 changes. Suggested reordering levels, several currencies in Point of Sale, price rules per packaging and the new returns flow may replace work you paid for in an older version. A module you drop is one less module to port.
Step 2: request an upgraded test database
- Odoo Online. In the database manager, choose the database, click Manage, then Upgrade, pick the target version and set the purpose to Test.
- Odoo.sh. Use the Upgrade tab on a staging branch. Odoo sends the latest daily backup of production to the upgrade platform; once it is back, every commit restores the upgraded copy and updates your custom modules. The log is in
~/logs/upgrade.log. - Your own server. Run the upgrade script on the machine that hosts the database:
python <(curl -s https://upgrade.odoo.com/upgrade) test -d <your-database> -t 20.0On your own server, the script needs access to PostgreSQL and outbound connections on port 443 and on ports 32768 to 60999, which a strict firewall may block. The copy goes up without the filestore, so merge the returned filestore folder with your production filestore before you test. Each completed upgrade comes with an upgrade report, by email and in Discuss for administrators.
Step 3: port the custom modules
Odoo’s guide is clear on the order: make each module install on an empty Odoo 20 database first, one by one, fix the errors, test it, clean the code, and only then run it on the upgraded copy, with upgrade scripts for any renamed fields or models. These Odoo 20 changes are where most of the work is:
| Change in Odoo 20 | What to check in custom code |
|---|---|
Access rights and record rules merged into one model, ir.access | Rewrite ir.model.access.csv and record rule XML as security/ir.access.csv, with columns id, name, model_id, group_id/id, operation and domain |
| Tracking values no longer stored by default | Code or reports that read mail.tracking.value; install the Discuss Tracking module if you need them |
| Inventory valuation moved into Accounting | Custom valuation reports and code that reads the old stock_account settings |
| Parent accounts replace account groups; account codes optional | Reports that group accounts by code prefix |
| Payment status labels renamed | Filters, automations and reports that use payment status |
| Return wizard removed | Customizations on returns |
| Material Symbols icons in Odoo’s screens | Icons in custom views and buttons, for a consistent look |
Step 4: test the upgraded copy
Test databases are neutralized: scheduled actions are off, outgoing mail goes nowhere, payment providers and carriers are in test mode, and bank synchronization is off. Run your real flows on it, with the people who do them every day:
- Buy a product, receive it with the Barcode app, and add a landed cost.
- Sell it, deliver it and print the Arabic and English invoice.
- Issue a credit note and register a payment, then check its status after bank matching.
- Open and close a Point of Sale session and check the entry it creates.
- Print product and location labels on your printers.
- Run payroll for one month if you use Odoo Payroll, and compare each payslip with the live one.
- Export data, run your saved filters, and check every custom report.
Report problems in the standard upgrade to Odoo through its support page, choosing the option for testing an upgrade. Fix custom module problems on your side and request a fresh test copy as often as needed, since your data keeps changing.
What to check in Kuwait
- Arabic documents. Check invoices, credit notes, delivery slips and statements in Arabic, with Arabic as the main language of the invoice, in line with the Ministry of Commerce and Industry’s rule.
- The dinar. Amounts, rounding and totals at three decimals, on screen and on every report.
- Payroll. Odoo 20 adds a base Kuwait payroll localization. If your payroll runs on a setup built by your partner, do not switch in the middle of a year: test the new package on the copy first and decide with your accountant.
- Group companies. Kuwait has no VAT, but a Saudi company in the same database should test ZATCA submission in the simulation environment, since Odoo 20 moved it into the Send wizard.
Step 5: reconcile and rehearse
Compare the upgraded copy with the live database on the same date: trial balance, aged receivables and payables, stock quantity and value per warehouse, and open sales and purchase orders. Odoo recommends a full rehearsal of the upgrade the day before production. Plan the date away from month-end closing and the payroll run.
Step 6: upgrade production
- Odoo Online. The same steps as the test, with the purpose set to Production. The database is unavailable until it finishes, and it cannot go back to the old version.
- Odoo.sh. The upgrade on the production branch starts with the next commit, so it runs together with your ported modules. If anything fails, the platform reverts it; on success it keeps a backup from before the upgrade.
- Your own server. The same script with
productionin place oftest. Stop using the database once it is uploaded, and merge the filestore before you go live.
In Kuwait a Friday and Saturday window usually works for distributors and back offices; retail with Saturday trade may prefer a weekday night. Keep the pre-upgrade backup, and ask the people who tested to check the live system on the first morning.
We run Odoo upgrades for companies in Kuwait and the Gulf, from the test copy to the first weeks after go-live: see our Odoo migration and upgrade service and Odoo support.
What to do next
- Make the list in step 1 and send it to whoever maintains your custom modules.
- Request a test upgrade to Odoo 20 and give your key users a week on it.
- Book a consultation if you want us to port the modules and run the cut-over.
