ISSUE 2026-09-27SERIES BREC 36TYPE BRIEFgarnetgrid.com
It is not the licence
Insights
Every ERP vendor locks you in to some degree, and that is not in itself a scandal. What matters is the size of the bill if you ever have to leave, and how much of that bill you are quietly agreeing to this quarter. The licence is the cheapest part of it. The expensive parts are the data model, the extensions you were encouraged to write, and the integrations nobody has ever inventoried.
The question worth asking about an ERP is not whether the vendor will lock you in. Every one of them will, to some degree, and a system of record that is easy to abandon is usually one nobody relies on. The useful question is narrower: if you had to leave in five years, what would it cost, how much of that cost is being created by decisions you make this quarter, and which of those could go the other way at no real loss. Very little of the answer has to do with the licence.
What makes an ERP hard to leave is that it gradually becomes the definition of your business's nouns. Customer, order, cost centre, item, work order. Once the warehouse scanners, the commission report and three regional finance teams all use the ERP's identifiers and its particular idea of what a customer is, the vendor's idiosyncrasies have become yours.
That coupling is semantic, not technical, which is why conversion tooling never resolves it. The schema is wide, the field names abbreviated, and much of the meaning is not in the schema at all but in configuration. Several fields on a document will look like dates and mean different dates: the date on the supplier's paper, the date the posting hits the ledger, the date somebody typed it in. Which one your revenue report uses is a business rule sitting in a configuration table someone set years ago and never wrote down.
That is not the vendor behaving badly; it is what a system of record looks like after a decade of real use. But exit cost is mostly a function of how much of your own vocabulary you let someone else's product define.
The extensions you were encouraged to write
Every ERP has its own extension language and lifecycle: ABAP in the SAP world, X++ for Dynamics 365 finance and operations, SuiteScript for NetSuite, Python modules for Odoo. Code written in those is not portable in any meaningful sense. It is portable as intent, which means somebody will have to read it and work out what it was for.
The number that predicts migration pain is not how many modules you licensed. It is the count of custom objects, and within that, the proportion nobody currently employed can explain. Measure that one: it is what turns a migration into an archaeology project.
The current vendor position is some version of "clean core": stop modifying the core, put extensions on our platform, upgrades stay cheap. The first half is good engineering advice. Be clear-eyed about the second half, because it moves your custom logic out of a database you could at least read and into a proprietary runtime with its own services, identity model and pricing metric. Usually still the right trade, but it is a trade: you now have a second supplier relationship with its own bill.
If custom logic must exist, the portable shape is a stateless service in a language and runtime you could host anywhere, called by the ERP over HTTP. The unportable shape is the same logic drawn in the vendor's workflow designer. Both work on day one. Only one survives the decision to leave.
Integrations are where the cost actually hides
In the estates we have worked in, the ERP itself is rarely the hard part. Everything wired into it is. Each connection encodes the vendor's interface style: its document formats, its batch windows, whether it offers idempotency or you built that yourself. Replacing the ERP means rewriting every one and re-testing the business processes on top, which is the expensive half.
It is worse when flows were built inside the vendor's own integration tooling by people outside IT. Those cannot be run or tested without the vendor, frequently cannot be diffed, and in practice cannot even be inventoried, because nobody holds the full list.
So make the list. One inventory, owned by you, of every inbound and outbound flow, with a named business owner and a sentence on what happens when it fails. It is a smaller job than it sounds, and it is the most useful artefact you will have when the migration question is finally asked. After that, keep new flows in your own repository, in code, with tests that run without the ERP being up.
The commercial shape, and the clause nobody reads
Pricing models differ in shape, and the shape matters more than the level: named users, consumption, or some proxy for business volume. The risk in all of them is re-interpretation rather than price: the metric is defined in a document the vendor maintains, and definitions of what counts as a user, or as access, have a habit of broadening. There is also a long-running dispute about indirect access: whether data reaching the ERP through another system is itself licensable consumption. Get that definition into the contract, not a policy page.
The deeper commercial point is asymmetry. The more integrated you are, the better the vendor's account team understands your switching cost, and your switching cost is their pricing power. Lock-in usually appears as a line on a renewal quote years before it appears as a migration project.
Then the clause nobody reads. You are obliged to produce financial records for some years after the transaction, depending on where you operate and what the record is. Your ability to read those records ends with your subscription. That conflict is cheap to fix at signature and expensive to fix later:
What actually reduces lock-in
Three things, in rough order of leverage.
Keep a canonical copy of your data outside the ERP, continuously, in an open format, in storage you control. Include the configuration tables and code lists, not only the transactions. A pile of transaction rows with no configuration beside them is not an exit plan, because the rows are uninterpretable without the settings that gave them meaning.
Own the semantic boundary. Write the mapping from the vendor's fields to your own vocabulary once, as code, in your repository, and have everything downstream read your model rather than theirs. That is the difference between replacing a system and replacing a worldview, and it pays off whether you migrate or not, because it also settles reporting arguments.
Decide deliberately which processes are commodity and which are yours. Let the ERP have the commodity ones unmodified, however the vendor shipped them, and keep the others in your own code. It is common to see this exactly backwards. They spend the customisation budget on procurement approvals and expense rules that every company does roughly the same way, then accept whatever came out of the box for the process their business actually competes on.
On hosting, since we are asked: running an ERP on hardware you own changes something real. You can read the database directly, at three in the morning, without asking. It does not reduce data-model or extension coupling. Self-hosting removes a question of permission. The binding you keep is meaning.
Rehearse the exit once, properly
Exit plans usually exist as a document. We have rarely seen one that has actually been run.
Running it looks like this. Take a full export, load it into a neutral store you control, then answer a real question with it: reconcile a month that is already closed, reproduce a customer statement including the attachment, recompute a stock valuation. You are not testing whether the file arrived, you are testing whether the export is semantically sufficient. The first time it will not be, and the reasons will be specific, unglamorous and fixable.
Do it while the relationship is good and the vendor's own people will still help. Do it before a renewal, so the conversation involves a number instead of a fear. Repeat it roughly yearly, because that is how you find out about the quarter they quietly deprecated the export you depend on.
Things that sound like answers and are not
Open-source ERP changes the permission, not the cost. The schema and extension coupling are identical in kind. You gain the right to fork, which is genuinely valuable and occasionally decisive, but a fork you maintain is a new obligation, and many organisations end up dependent on one implementation partner who becomes the lock-in instead.
Middleware relocates coupling rather than removing it, and if the middleware is the ERP vendor's own, it has not relocated far.
A warehouse or lake copy solves reporting lock-in, which is worth solving, and does nothing for operational lock-in. You cannot post a journal to a lake.
A general abstraction layer over the whole ERP does not work. At the boundary of your own code, yes. As a wrapper meant to make the ERP swappable, no, because the semantics leak: posting periods, document number ranges, fiscal calendars and the exact moment a document becomes immutable all surface in your supposedly neutral interface.
Pick the three that fit in a quarter: the integration inventory, a canonical export that includes configuration, and one honest exit rehearsal against a real question. Do the contractual work before signature, because afterwards you are asking a favour rather than negotiating a term. And set the goal correctly. Zero lock-in is not something an ERP can sell you. A known, roughly flat switching cost you measured yourself is, and at renewal that is worth more than an assurance from anybody, us included.