Skip to Content

Odoo Migration

Odoo Migration and Upgrades: What It Takes to Move Versions

An Odoo upgrade is not one project, it is three: the database, the custom code, and the people. The database is the part everyone plans for, and it is almost never the part that goes wrong.

The three projects inside one upgrade

Teams plan an upgrade as a database operation and are surprised by the schedule. It is more useful to see it as three parallel efforts with different owners.

The database. Convert the schema and the data from one version to the next. This is largely mechanical, it is the part Odoo's own upgrade service handles, and it is rarely the bottleneck.

The code. Every custom module has to work against the new framework. This is where the time goes, and the amount of time is decided by how the modules were written years earlier, not by anything you can influence now.

The people. Screens move, fields are renamed, reports look different. If the finance team cannot close the month in the new version, the upgrade has not succeeded no matter how clean the conversion was.

Budgeting the first and forgetting the other two is the single most common planning error.

The version path

Odoo ships a major version roughly annually. Upgrades move through versions in sequence rather than jumping directly, so a move from 15 to 19 is a series of conversions, whether or not you observe the intermediate steps.

The important consequence is about custom code rather than data. Upgrading annually means absorbing one year of framework changes at a time, each of them small. Upgrading every four years means absorbing all of them at once, in a single testing cycle, with no working intermediate state to compare against. The total work is similar. The risk is not remotely similar.

The other decision that lives here is hosting. Moving between Odoo Online, Odoo.sh and self-hosted is a migration in its own right, with different constraints from a version upgrade, and doing both at once doubles the number of possible explanations when something behaves oddly. Separate them.

What actually breaks

Version 19 ships a command, `odoo-bin upgrade_code`, that rewrites known renames in your source automatically. It handles things like the `` to `` view rename, the move of SQL constraints from the old list attribute to the newer class-level form, and the JSON-RPC route type change. Odoo's own documentation for it says plainly that these scripts are best-effort and not silver bullets, which is the correct expectation to hold.

What automated rewriting cannot touch is the category that actually costs money.

Views that were replaced rather than inherited. A copied core view keeps working until the version where core changes and yours does not. Nothing errors. The screen is simply missing whatever was added upstream.

Methods overridden without calling super. Your version of the method silently drops whatever the new version added to the original.

Renamed fields. Inside Odoo a rename is handled. Anything reaching in by field name is not: reports, dashboards, integrations, saved filters and exports all refer to the old name and stop matching.

Data that needs converting, not just moving. When a field changes type or a model is split, existing rows need a migration script in the module's `migrations/` directory, using the `pre-`, `post-` and `end-` hooks that run before initialisation, after it, and after all modules have loaded. Omit it and the module installs cleanly onto data that is quietly wrong, which is worse than a failure.

Reports and documents. Layout changes, and a customer-facing invoice that renders subtly wrong is discovered by a customer.

Testing that is worth the time

The pattern that works is unglamorous: take a copy of production, upgrade it, and have real users do real work in it.

Not a demo database. Not a subset. Production data is where the awkward records live, the ones with historical values and missing optional fields and characters nobody planned for, and those are precisely the records that break things.

Give the test a definition of done that is written before it starts. Not "it works", but a list: finance can close a period and the trial balance matches, the warehouse can receive and ship, each integration has completed a full cycle, the five reports the business actually uses produce the same numbers as the old version. Numbers that match are the only evidence that carries weight in a go-live decision.

Expect more than one round. The first upgrade of a customised database finds problems; the value is in how quickly you can repeat the cycle after fixing them. If a test upgrade takes a week to prepare by hand, you will do it once and go live on a single data point.

Rollback, decided in advance

Rollback is a plan, not a capability. It means a tested restore procedure, a named person who can authorise it, and a deadline after which it stops being an option.

That deadline is earlier than people expect. Once users have entered a day of real transactions in the new version, restoring the old database means losing that day. So the practical decision window is hours, which is why the go-live checks need to be fast, specific and rehearsed rather than exploratory.

Freeze the data during the cutover. An upgrade running against a database people are still writing to produces a result that matches neither the before nor the after.

Migrating from another system

Moving to Odoo from a different platform shares the vocabulary and almost none of the mechanics. There is no conversion path, only an extraction from the old system and an import into the new one, and the work is nearly all in the mapping.

Two decisions dominate the schedule. How much history do you bring? Open balances and open documents are usually required; ten years of closed transactions usually are not, and importing them anyway makes every subsequent step slower for the sake of data nobody queries. How clean is the data? A duplicate-ridden customer list migrated faithfully becomes a duplicate-ridden customer list in a new system, and the migration is the last convenient opportunity to fix it.

Validate by reconciliation, not by inspection. Record counts, control totals and open balances that match the old system are proof. Opening a few records and finding them plausible is not.

What drives the cost

Upgrade quotes vary widely for the same database size, and the variation is almost entirely explained by customisation.

The cost drivers, in rough order: the number and quality of custom modules, the number of integrations, how many versions are being crossed, whether reports were customised, and how much business validation the organisation requires before it will sign off. Data volume matters far less than people assume, and user count barely matters at all.

This is also why upgrade cost is really a development decision made years earlier. Modules that extend cleanly cost little to carry forward. Modules that fight the framework are paid for again at every version, and that recurring bill is usually larger than the original build.

If you are getting quotes, the useful thing to send is an inventory of custom modules and integrations, not a database size. Anyone who quotes without asking for it is guessing.

In this guide

Go deeper on one part of it.

The pillar above is the overview. These take one question each and answer it properly.

The Odoo Version Upgrade Path, and Why Skipping Costs MoreOdoo upgrades move through versions in sequence rather than jumping. That single fact explains most of what is confusing about upgrade quotes, and all of why a database four versions behind is a different kind of project from one that is one behind.Read itWhat Actually Breaks When You Upgrade OdooUpgrades rarely fail loudly. The database converts, the modules install, everyone signs off, and the problems surface three weeks later in a report that does not tie out. These are the failure modes worth testing for, in the order they cost money.Read itAn Odoo Upgrade Testing Strategy That Finds Real ProblemsMost upgrade testing fails the same way. Someone opens the new version, clicks around, finds nothing obviously broken and signs it off. Three weeks later a reconciliation fails. The fix is not more testing, it is a test with a pass condition written before it starts.Read itMigrating Custom Odoo Modules Between VersionsCustom modules are where upgrade budgets are actually spent. The database conversion is largely mechanical and the business validation is predictable. The code is the variable, and how much it costs was decided years ago by whoever wrote it.Read itOdoo Migration Rollback Planning: Deciding Before You Need ToEveryone says they can roll back. Almost nobody has decided who authorises it, what would trigger it, or the hour after which it stops being possible. Those three answers are the plan, and they have to exist before go-live night, not during it.Read it

FAQ

Odoo Migration, answered.

How often does Odoo release a new version, and do I have to upgrade?

A new major version arrives roughly once a year. You are not forced to move immediately, but each version is supported for a limited window, and the further behind you fall the more versions an eventual upgrade has to step through. Staying two or three versions back is normal. Staying six is a rebuild.

Can I skip versions and go straight from 15 to 19?

The database upgrade is performed as a sequence of steps rather than a single jump, so in practice you are doing several upgrades whether you see them or not. Custom code is where skipping hurts, because you inherit four years of framework changes at once instead of in annual increments.

How long does an Odoo upgrade take?

The technical conversion of a clean database is often hours. A real project is usually weeks, because the time goes into fixing custom modules, retesting integrations and running the business validation that decides whether you can actually go live.

What does an Odoo upgrade cost?

It scales with customisation, not with data volume or user count. A near-standard database is modest. A heavily customised one costs in proportion to how much of that customisation fights the framework rather than extending it. Ask for the custom module inventory before asking for a number.

Is Odoo's own upgrade service enough?

It handles the database conversion, which is real work you do not want to do by hand. It does not fix your custom modules, revalidate your integrations or decide whether the results are correct. Those remain yours, and they are the larger share of the effort.

Can we go back if the upgrade goes wrong?

Only if you planned to. Rollback means a tested restore procedure and a decision point with a time limit, agreed before go-live. Once users have entered a day of transactions in the new version, going back means losing that day, so the rollback window is much shorter than people assume.

Do we have to upgrade to keep getting security fixes?

Supported versions receive fixes; unsupported ones do not. That is the practical reason an upgrade eventually stops being optional, regardless of whether the new features interest you.

Related

Keep exploring.

Other Odoo apps we have written up in the same depth.

With CODEerts

Planning an upgrade?

We are certified Odoo partners. We migrate and upgrade Odoo databases, including the custom modules and integrations that decide how long it really takes.

See how we can helpBook a call