Of the 2,000 modules that install on Odoo 17 from the Odoo Community Association's repositories, 1,073 have an installable version for Odoo 19 and 66 have one for Odoo 20. Those modules are the part of an Odoo upgrade cost that Odoo does not carry: its own upgrade service converts the standard apps and leaves every module somebody else wrote to you, unless it is under an Odoo maintenance contract. A database carrying one "cannot be upgraded until a version of your custom modules is available for the target version", in the words of Odoo's upgrade documentation.
Odoo 17 end of support makes the count due. Standard support for 17 ended in September 2026, the month Odoo 20 shipped, and staying has its own bill: a 25% surcharge written into Odoo's subscription agreement, from March 2027 at the earliest, and no security fixes from the day support ended.
CloudSpinx, which implements and upgrades Odoo for businesses in Kenya, counted the modules across the OCA's 270 non-archived repositories, branches 17.0 to 20.0, and read the manifest of every Odoo 17 module and of its namesake on 18, 19 and 20 instead of trusting that a folder exists. That last part matters. Of the 137 module folders on the OCA's 20.0 branches, 45 are placeholders marked not installable.
What Odoo 17 end of support changes, by where it runs
Odoo releases one major version a year and gives each three years of standard support, so 17 dropped out when 20 arrived. Odoo's support table then splits by hosting:
| Where Odoo 17 runs | Support since September 2026 | Security fixes | When you have to move |
|---|---|---|---|
| Odoo Online | None | None | Odoo moves you: a major version must be upgraded every two years, automatically if you do not act |
| Odoo.sh | Extended, for an additional fee | None | Within two more years after standard support ends |
| Your own server | Extended, for an additional fee | None | Never forced. Odoo lets you stay indefinitely |
"Security updates are only provided during standard support," the table's page says. Bug fixes continue in extended support "only where technically feasible", and Odoo's public source shows how fast the commits thin out. The 16.0 branch took 1,398 commits in its last twelve months of standard support and 206 in the twelve after, about one in seven. The 17.0 branch took 1,714 in its last twelve months and 86 in October 2026, its first full month out. The thinning starts before the date: 16.0 was down to 39 commits in its last month of standard support, 17.0 to 101. The 15.0 branch stopped outright: its last commit landed on 1 November 2024, right after its standard support closed in October, and nothing has followed, though Odoo still lists 15.0 under extended support.
The 25% fee for staying on Odoo 17
Clause 5.1 of the Odoo Enterprise Subscription Agreement sets it. Once a year, and no earlier than six months after a new major version is released, a database older than the three most recent versions pays "an extra fee equal to 25% of the annualized price, calculated based on the Customer's current per-user price and number of Users and Light Users." Odoo 20 was released in September 2026, so a 17.0 database meets the fee from March 2027 at the earliest.
A quarter of the annualized user price is three months of it, paid again every year you stay. Odoo prices per user and per country (what the plans come to in Kenya), so the user lines of your own invoice are the number to multiply. The support page says extended support "requires an additional fee" and prints no figure. The 25% is the only figure for staying on an old version that we found in Odoo's published terms.
Two more sentences in the same agreement bite if you stay. A bug reported on an uncovered version may be answered with an upgrade: the customer "might be asked to upgrade to a more recent Covered Version of the Software as a remedy to a Bug". And the agreement treats non-compliance as a bug at Odoo's discretion, typically "when a country-specific feature does not meet legal accounting requirements anymore". On our reading, a KRA change that breaks invoicing on 17 is the case the agreement describes, and Odoo may answer it by asking you to upgrade.
What Odoo's upgrade service covers, and what it leaves on your bill
On a subscription, Odoo converts the standard apps at no extra fee, Studio customizations while Studio stays installed and the subscription stays active, and any module under a maintenance-of-customizations subscription. It does not clean your data, train your staff, or upgrade "additional modules not covered by a maintenance contract that are created in-house or by third parties, including Odoo partners". Unless it is under maintenance, every OCA module, every Apps Store purchase and everything a partner wrote for you sits in that clause.
Maintenance has its own meter, and self-hosted it runs through an Odoo partner: dealing with Odoo directly, the agreement provides it "if and only if the Customer is hosted on the Odoo Cloud Platform". The agreement charges "a monthly fee per 100 lines of code", counted with Odoo's cloc command, at a rate set in your contract, and the pricing page lists maintenance of custom code under what the plans leave out. When you request the upgrade, Odoo "may charge a one-time extra fee for each missing month of coverage" for any covered module that went without maintenance in the last 12 months. On that wording, enrolling a module the week before the upgrade does not skip the year.
A database with no subscription has none of this. The upgrade service runs "for the duration of this Agreement", so a Community install with no subscription usually goes through the OCA's OpenUpgrade project or a hand-written migration.
How many OCA modules have an Odoo 18, 19 or 20 version
Of the 2,000 installable 17.0 modules, 1,591 (79.6%) have an installable module of the same name on 18.0, 1,073 (53.7%) on 19.0 and 66 (3.3%) on 20.0. 322 have none of the three. OpenUpgrade's rename and merge tables account for 21 of those (sale_commission became sale_commission_oca, hr_attendance_autoclose went into Odoo's own hr_attendance), which leaves 301 with no successor recorded in those tables.
The repositories move at very different speeds. 52 of the partner-contact repository's 74 Odoo 17 modules have a 19.0 version. For the point-of-sale repository it is 2 of 45.
Checking a module of your own takes one request per branch, and the version string is what gives a placeholder away. This one has a folder on 20.0 and is not a port:
$ for b in 19.0 20.0; do echo "== $b"; curl -s \
"https://raw.githubusercontent.com/OCA/storage/$b/fs_attachment_s3/__manifest__.py" \
| grep -E '"(version|installable)"'; done
== 19.0
"version": "19.0.1.2.1",
"installable": True,
== 20.0
"version": "19.0.1.2.1",
"installable": False,
If your module list leans on the OCA, send it to us through the ERP scoping form and we will mark each module against 18, 19 and 20 before anyone prices a port.
Community databases meet a second gate. OpenUpgrade's coverage table for 17.0 to 18.0 lists 554 modules that exist on 17.0, 260 of them marked Done or Nothing to do and 294 with no status. The 18.0 to 19.0 table lists 603 that exist on 18.0, with 268 marked. Its 20.0 branch holds no migration scripts yet, and the pull request that migrates base was still open when we read it. A Community database on 17 can aim at 18 or 19 that way. Not 20.
eTIMS and the server underneath
For tax invoicing, Odoo's Kenya documentation for 16.0 covers only the older Tremol TIMS device. From the 17.0 page on, Odoo documents eTIMS through its own OSCU modules, which the 19.0 page names as l10n_ke_edi_oscu plus manufacturing and point-of-sale companions. None of them is in the public Community source on any branch from 16.0 to 20.0, which carries only l10n_ke and l10n_ke_edi_tremol. On Enterprise, Odoo's own eTIMS modules are therefore standard apps the upgrade service converts. On Community, or with a third-party integration, the eTIMS link is code you or someone else wrote, and it joins the port list at every upgrade, OSCU or VSCU alike.
The other line is the server. Odoo's install pages raise the minimum to PostgreSQL 13 for Odoo 19, and for Odoo 20 to PostgreSQL 16 and Python 3.12. Ubuntu 22.04 still ships PostgreSQL 14 (end of life 12 November 2026) and Python 3.10, so a 17.0 server on that stock release clears 18 and 19 on both counts and needs both upgraded before 20.
Working out your own Odoo upgrade cost
- Multiply your yearly user charge (each user type's price times its count, Users and Light Users) by 0.25. That is the clause 5.1 fee for keeping a self-hosted or Odoo.sh database on 17, charged once a year from March 2027 at the earliest, and it buys no security advisories.
- List every installed module Odoo did not write, and for each OCA one read the target branch's manifest as above. The newest version where every module you keep has an installable version is your ceiling.
- Run
odoo-bin cloc -c config.conf -d my_database. It counts the extra modules installed on the database plus the server actions and computed fields created in it. Odoo calls the result "a rough metric for pricing maintenance of extra modules". - Run
SHOW server_version;in psql andpython3 --versionon the server. PostgreSQL under 16 means a PostgreSQL upgrade before Odoo 20 (under 13, before 19), and Python under 3.12 means a newer Python before 20.
Then check the calendar against the answer. Odoo's table plans the end of 18's standard support for September 2027, so a database moved to 18 meets this question again within a year, and 19 buys one more.
On Odoo Online or Odoo.sh with nothing but standard apps and Studio, the subscription already pays for the conversion, and what is left is what Odoo leaves to every customer: testing the upgraded copy, cleaning up pre-existing data it trips on and showing staff what changed. That is work for your own people, not for a contractor. Self-hosted, add installing the new Odoo version, the filestore merge Odoo's procedure describes, and the server checks in step 4.
Everyone else can write "Odoo upgrade from 17" in "What do you need?" on the ERP scoping form, pick "Port an existing custom module" and "Odoo", and paste into "Anything we should know?" the hosting (Online, Odoo.sh or your own server), the edition, the module list with where each came from (OCA, the Apps Store, written for you), the cloc total and the PostgreSQL and Python versions, or send the same on WhatsApp at +254 713 403 044, where a long module list can go as a file. You get every module marked ported, needs porting, replaced by standard Odoo or dropped, the version to aim at and one figure for the move. When the port is ready we run the move with you, on a test copy first, the way Odoo's own procedure does. There is no charge for the marked list and no obligation to buy the port from us.