The Odoo upgrade you end up paying for
Odoo ships a major version every year. What it costs you to move to it was decided during your implementation, by choices that felt small at the time.
Odoo releases a major version annually, and support for older versions does not run forever. So at some point every implementation faces an upgrade, and businesses discover that theirs is either routine or a project.
Which of those it is was determined years earlier, by decisions that were made in a workshop and did not look consequential.
The three kinds of change, and what each costs at upgrade time
Configuration. Settings, fields you enabled, workflows built with the tools the product provides, pricing rules, warehouse routes. This survives an upgrade. It is what the product is designed to let you do, and it should be the default answer to almost every requirement.
A custom module written against documented interfaces. Real code, in its own module, using the extension points Odoo publishes. This survives an upgrade with work: something in the API it relies on may have changed, so it needs testing and occasionally adjusting. Predictable, bounded, and worth it when the requirement is genuinely yours.
Anything that reaches around the product. Modifying core files, writing directly into tables, or depending on internals that were never a published interface. This does not survive. At upgrade time it either breaks silently or has to be rebuilt, and because it was never documented as an interface nobody can tell you in advance which.
The awkward truth is that the third category is often the cheapest way to satisfy a requirement in the moment. That is exactly why it needs to be a decision the business makes knowingly rather than one an implementer makes quietly.
The compounding part
Customisation debt does not sit still. Each version you skip makes the next move larger, because you are now jumping several sets of API changes at once. Businesses that stay two or three versions behind because the last upgrade was painful find the next one worse, which makes them delay again.
The other compounding factor is volume. Twelve small customisations, each individually reasonable, is a bigger upgrade than one substantial module, because each one has to be tested independently.
Questions to ask during implementation, not after
These are cheap to ask now and expensive to ask later.
- Is this configuration or code? For every requirement. Get the answer written down.
- If it is code, what interface does it use? A documented one, or an assumption about internals?
- What happens to this at the next major version? If the answer is nobody knows, that is the answer.
- Could a process change remove the need entirely? Sometimes the customisation exists to preserve a way of working that nobody would defend if asked directly. That is the cheapest customisation available: the one you do not build.
- Who is paying for the upgrade, and is it in the budget? An implementation quote that does not mention upgrades has quietly deferred a cost.
Living with it well
Keep a register of every deviation from standard, what it does, why, and what interface it depends on. This is twenty minutes per item during implementation and it is the document that makes the upgrade quotable rather than exploratory.
Upgrade on a cycle rather than when forced. Staying current is a series of small predictable pieces of work. Falling behind converts it into one large unpredictable one.
Test in a copy, with your data, before anything. Obvious, routinely skipped.
Where we stand on it
We will build custom modules, because sometimes the requirement is real and the standard configuration genuinely does not reach. We will not modify core or write directly into the database on a client’s production system, and if a requirement can only be met that way we would rather say so and discuss the alternatives than leave someone an upgrade they cannot afford.
That is a less accommodating answer in month two of an implementation. It is the reason the upgrade in year three is a maintenance task rather than a rebuild.