Every hour of custom code is an hour somebody maintains through every future upgrade, forever. That is not an argument against custom development — it is an argument for deciding deliberately rather than by default.
Roughly 95% of what we deliver is standard Odoo configured properly. The remaining 5% is genuine, and getting that boundary right is one of the more consequential decisions in an implementation.
The real cost of custom code
The quote you receive covers building it. What it does not cover is what happens afterwards.
- Every upgrade. Odoo releases annually. Well-written modules survive; badly written ones need rework each time.
- Every new developer. Someone has to understand it before they can safely change anything near it.
- Every adjacent change. Custom code constrains what standard functionality you can adopt later.
- Institutional memory. In three years, the person who specified it will have forgotten why.
None of that makes custom development wrong. It means the benefit has to be worth carrying that weight.
Where it is usually justified
Integrations
Connecting Odoo to a payment gateway, a logistics provider, a bank or a marketplace. These are well-defined, the benefit is obvious, and the alternative is somebody re-keying data. Most integration work pays back inside months.
Genuinely differentiated processes
If your business competes on something specific — a pricing model, a service workflow, a quality process nobody else runs — that is worth building. It is why you win work.
Regulatory requirements
Where compliance demands something standard Odoo does not do, there is no choice. Much of the ZATCA Phase 2 work falls into this category.
Volume-driven automation
A manual step taking two hours a day is roughly 500 hours a year. Automating it usually pays for itself in one.
Where we push back
Rebuilding your old system. The most common request, and the one we resist hardest. "Our previous software did it this way" is a description of a constraint, not a requirement. Often the old way existed because the old system forced it.
One person's preference. Features requested by a single user that nobody else will touch. These get built, used twice, and maintained forever.
Cosmetic differences. Odoo does the thing, just with different labels or a different screen order. That is a training question, not a development one.
Building it so it survives
Where the case is genuine, how it is written determines whether it becomes a liability.
- Inherit, do not override. Extending standard behaviour survives upgrades; replacing it does not.
- Use the ORM. Raw SQL bypasses Odoo's business logic, access rules and audit trail.
- Keep it in its own module. Separable, removable, testable.
- Document why, not just what. The next developer needs the reasoning.
- Specify before you code. Vague scope is how development projects overrun.
A question worth asking your partner
When you request a customisation, does the partner push back? A partner who agrees to everything is optimising for the invoice rather than your total cost of ownership. The right answer to most customisation requests is "let us change the process instead" — and hearing that occasionally is a good sign.
More on this in our piece on choosing an Odoo partner.
Have a requirement configuration cannot meet?
Tell us what you need. We will tell you honestly whether it needs building or whether Odoo already does it.
Book a discovery call