Some Odoo customizations survive an upgrade almost untouched, and some break outright, and which one you get is decided on the day the customization is built, not on the day you upgrade. A field added through Odoo Studio and a custom module that overrides a core method are both changes to the same system, and each is a different bet on how the next version treats what you built.
This is not a question of whether to customize Odoo, or which method to use. Assume both decisions are already made: something was built, in Studio or in code, and has been running for a year or three. What follows is what happens to it on upgrade day: why some of it survives unnoticed, some breaks the morning after go-live, and what to do about the difference before the upgrade starts.
What usually survives an upgrade
Some categories of change move to a new Odoo version with almost no drama, because they were never really code a future release could contradict.
- Configuration. Settings, toggles, sequences, and workflow stages are data, not a program a new version has to reinterpret, so they move forward like any other record.
- Price lists and approval rules. Customer-specific pricing, quantity breaks, and approval thresholds are records, not custom logic, and migrate like any other data.
- Access rights. Who can see, edit, or approve what is a matter of groups and permissions, rarely rewritten by an upgrade.
- Automated actions. Odoo’s automation rules are a supported, documented mechanism, so upgrade scripts already know how to carry them forward.
- Email templates. Wording, timing, and recipients update cleanly, since templates use a stable placeholder syntax Odoo maintains version to version.
- Most added fields. A field added to hold a value, with no logic hanging off it, usually reappears on the new form without incident.
- Well-written modules that extend rather than override. A module that adds a method, or listens for an event, is additive. Odoo’s own code underneath stays untouched, so there is nothing to conflict with.
Everything here is additive or declarative. None of it reaches into Odoo’s own code and changes how it behaves internally.
What usually breaks
The other list is shorter, and it is where nearly all upgrade pain concentrates.
- Code that overrides a core method instead of extending it. A module that replaces how Odoo calculates a total or validates a record is betting the method it hooked into looks the same next version. It often does not.
- Anything depending on a specific view’s internal structure. A customization that finds a field by its exact position on a form, or inherits a view by matching XML it did not write, breaks the moment Odoo rearranges that screen.
- Undocumented Studio sprawl. A field or automation added through Studio is not the problem. Forty of them, added by different people with no record of why, are the real issue: nobody upgrading the system knows which still matter.
- Modules pinned to a removed API. Odoo deprecates internal methods between versions like any mature platform, and a module written against a removed one does not degrade. It fails to load.
- Customizations that duplicated a feature Odoo has since built in natively. The custom version and the native version rarely agree on how a record should look, and the conflict usually surfaces in production, not in testing.
Each item here depends on something outside its own definition: a method’s behavior, a screen’s layout, an API that may not exist, rather than a stable interface.
Survival odds at a glance
A working guide to how these categories behave in real upgrade projects.
| Change type | Typical upgrade impact | What to do before upgrading |
|---|---|---|
| Configuration, price lists, approval rules | Minimal, these move as data | Spot-check after the upgrade |
| Access rights and automated actions | Low, both are supported mechanisms | Confirm triggers still fire on staging |
| Simple added fields and email templates | Low | Confirm fields render and templates resolve |
| Module that extends Odoo rather than replacing it | Moderate, needs a compatibility pass | Test on staging; bump the manifest version |
| Module that overrides a core method | High | Full code review before touching production |
| Customization tied to a view’s structure | High | Rebuild the view inheritance; do not port as-is |
| Undocumented Studio sprawl | High, mostly from unknown scope | Full inventory before the upgrade starts, not after |
| Module pinned to a removed API | Breaks outright | Rewrite against the current API, or retire it |
| Customization duplicating a now-native feature | Survives technically, but conflicts with the native version | Delete it and adopt Odoo’s own |
Why “Odoo changed it” is often good news
A recurring moment in any upgrade project: a customization built two or three versions ago turns out to duplicate something Odoo has since added natively. The instinct is to defend it, since it took real budget to build and someone is attached to it. The better move, almost always, is to delete it and adopt Odoo’s own version instead.
The reasoning is simple. A custom feature is something your team, or your Odoo partner, has to re-test at every future upgrade, indefinitely. A native feature is something Odoo tests and maintains on its own schedule. Every custom feature retired in favor of a native equivalent is one less thing on your side of that ledger, permanently.
The hard part is rarely technical. It is organizational: someone has to notice the overlap, and be willing to say a customization that felt necessary two years ago no longer earns its keep. Odoo does not announce that it built your feature. It just ships it.
The pre-upgrade audit
Every upgrade should start from a full list, not a memory of one. Four steps, in order.
- Inventory every customization. Every custom module, Studio field, automation, and overridden view, gathered into one list rather than scattered across whoever remembers building it.
- Mark each one keep, retire, or replace with standard. Keep what still earns its cost. Retire what nobody can justify. Replace what Odoo now does natively.
- Test the result on a staging copy loaded with real data. Not a blank database, the same records and volume your business actually produces, since that is where real behavior shows up.
- Upgrade only what you still need. Anything marked retire should leave the system before the upgrade, not travel through it out of habit.
If nobody currently has a complete answer to what is actually customized, an outside Odoo audit is built for that gap: a structured, independent read of the code and configuration, rather than relying on whoever has been there longest.
Build for the next upgrade, not just for now
Everything above describes handling customizations that already exist. The cheaper version of this problem is building new ones so the next upgrade needs none of it.
- Extend, do not override. Add a new method or listen for an event, rather than replacing Odoo’s own code, even when the override looks like less effort today.
- Keep logic in modules under version control. Code in a repository carries a history: who wrote it, and what it replaced. A database-only change carries none of that.
- Document why each customization exists, not only what it does. “Tracks the state’s certificate number” survives a staff change. A field with no explanation becomes a mystery within a year.
- Avoid duplicating a standard feature. Check whether the current version, or the one you are moving to, already covers the request before a developer starts.
- Review the customization list at every upgrade, not only when something breaks. A list reviewed on a schedule stays short. One nobody reviews grows for years first.
This is the standard our own Odoo customization work follows, and what a standing support plan reviews at every version bump, since version-upgrade management comes standard with a fixed-fee plan. As an official Odoo Partner, we took one client, Armor Concepts, up four Odoo versions at once, from 16 to 19, keeping the custom logic behind their multi-channel sales intact throughout.
The compounding cost of skipping the upgrade entirely
Everything above assumes the upgrade happens. Skipping it does not freeze the risk in place. It compounds it.
Odoo supports a limited window of recent major versions. Fall outside it, and official support most partners rely on to fix a real bug disappears, along with security patches. None of the customization risk above goes away either. The gap to the current version only grows, and the eventual upgrade has to cross more ground at once.
There is also a direct cost most teams do not expect: Odoo applies a 25% legacy surcharge to Enterprise subscriptions that fall too many versions behind. Our own Odoo upgrade page breaks down the current version-support window and what that surcharge looks like in practice. Staying still is rarely the cheap option it appears to be.
The honest bit
None of this argues against customizing Odoo. It argues for knowing what each customization costs once the invoice for building it is paid. Every piece of custom work, however well built, adds one more thing to check at the next version change, and sometimes to rebuild. That bill is smaller for a well-built module than for an undocumented Studio field, but it is never zero.
Building only what genuinely earns its cost, and building it well, keeps paying for itself at every future upgrade, not only on the day it ships.
Upgrades are not risky because Odoo changes. Odoo changes every year, on a published schedule, and most of the system moves through that without anyone noticing. Upgrades are risky in direct proportion to how much undocumented, unreviewed custom work you are carrying at the moment the upgrade starts. Carry less of it, know what you are carrying, and the next upgrade stops being an event.
Frequently asked questions
Do Odoo customizations break when you upgrade?
Some do and most do not. Configuration, price lists, access rights, automated actions, and well-written modules that extend rather than override typically carry through cleanly. The ones that break usually reached into Odoo’s own code, depended on a screen’s layout, or were never documented.
What happens to custom modules during an Odoo upgrade?
A module that extends Odoo, rather than overriding core methods, usually needs only a compatibility check and an updated manifest version. One that overrides core behavior, or targets a removed method, needs a real code review and sometimes a rebuild. If that capacity does not exist in-house, that is the gap hiring an Odoo developer closes.
Do Studio changes survive an upgrade?
Individually, most do, since Studio changes are stored as data rather than code. The real risk is rarely one field or automation. It is dozens of them, built up over years, with nobody able to say why each exists. That volume, not the tool, makes a Studio-built system slow and expensive to upgrade.
How do I prepare customizations for an Odoo upgrade?
Start with a complete inventory, not a guess. Mark each item keep, retire, or replace with a standard feature. Test the result on a staging copy loaded with real data and volume, not a blank database. Then move what you kept into production.
Should I remove customizations before upgrading?
Remove the ones nobody can justify, and the ones that duplicate a feature Odoo now provides natively. Keep the ones tied to a real business requirement, a contract, or a workflow only your business runs. The upgrade is the natural moment to make that call, since the audit already surfaces the list.
How often should I upgrade Odoo?
Odoo ships a new major version roughly once a year and actively supports the three most recent releases. Staying inside that window, rather than waiting until support ends, keeps each upgrade smaller and each customization review shorter. The section above covers what falls outside it and what that costs.
If you are staring down an Odoo upgrade and are not sure what you are actually carrying, bring your customization list to a free demo and we will help you sort what survives from what needs work.


