Skip to main content

Lesson 5 — Lock-in and portability

Lock-in discussions tend to be either dismissive ("everything locks you in, get on with it") or paranoid ("use nothing proprietary"). Both cost money. The useful position is knowing which forms are expensive to unwind and which are trivial.

Five kinds, ranked by how much they hurt

1. Data gravity — the heaviest by far

Your data is where it is. Moving petabytes is slow, expensive in egress fees, and disruptive to everything that reads it.

This is the real lock-in, and it is the reason lesson 2's advice is to use the platform where your data already lives. Everything else is comparatively minor.

What helps: open storage formats — Parquet, Delta, Iceberg — so at least the data is readable elsewhere once moved. And avoid architectures that continuously move data between providers, since you pay egress forever for the privilege.

2. Proprietary managed APIs — moderate, and containable

If your product depends on a specific provider's document extraction or transcription service, replacing it means integration work and re-validating quality, because the competing service will behave differently on your data.

What helps: an interface in your own code between your application and the service, so a replacement is one implementation rather than changes scattered across a codebase. This is ordinary engineering hygiene and it costs almost nothing when done from the start.

3. Platform-specific orchestration — moderate, and often overestimated

Pipelines written in a platform's own SDK do not run anywhere else. Rewriting them is real work.

What helps: put your actual logic in containers and use the platform for scheduling and orchestration. A training step that is a container reading from storage and writing a model runs anywhere; a training step written against a platform's proprietary estimator classes does not. The container boundary is where portability is cheapest to buy.

4. Model formats — mild

Models saved in a framework-specific format are portable in practice, because the frameworks themselves are portable. Formats such as ONNX add a further layer of neutrality when you need it.

Rarely the binding constraint.

5. Skills and habits — mild, and underestimated

Your team knows one platform's console, its quirks and its failure modes. That knowledge does not transfer, and rebuilding it takes months of reduced effectiveness.

Real, and rarely decisive on its own.

What is worth doing, and what is not

Worth doing, because it costs almost nothing:

  • Keep training and inference logic in containers
  • Keep data in open formats
  • Put an interface between your code and any proprietary service
  • Keep code in your own version control, not a platform's notebook storage
  • Store model artefacts in object storage you control
  • Know roughly what a migration would involve, even if you never do it

Not worth doing:

  • Multi-cloud for its own sake. Running the same workload on two providers doubles operational effort permanently to insure against something that rarely happens. There are good reasons for multi-cloud — acquisitions, regulatory demands, a genuine capability gap — and generic risk aversion is not one.
  • Avoiding managed services entirely. The productivity you give up exceeds the migration you avoid, in almost every case.
  • A least-common-denominator abstraction layer. Building your own wrapper over three providers' services means you maintain a wrapper and get the weakest feature set of the three. This is a well-trodden path to a large internal project with no users.

The exception worth building for

Hosted model APIs are the one place where cheap switching genuinely pays.

The leading model changes every few months, prices move, and models get deprecated with modest notice. Here, a thin interface in your code and a preference for gateway services that expose several model families is straightforwardly worth it — you will exercise that option, probably more than once a year.

Contrast with your data platform, which you will likely never move. Spend portability effort where you will use it.

Exit planning, briefly

Regulated organisations are increasingly required to document how they would leave a provider. Even where not required, a short version is worth having:

QuestionWhy it matters
Where is the data, in what format, how big?Determines whether a move takes days or quarters
Which proprietary services are we using?Each is a replacement project
Is our logic in containers or in platform SDKs?The difference between porting and rewriting
Could we retrain from scratch elsewhere?Tests whether your pipeline is genuinely reproducible
What would this cost, roughly?Turns an anxiety into a number

The exercise is valuable beyond its stated purpose: teams that cannot answer question four have a reproducibility problem that will bite them long before any migration.

The balanced position

Accept data gravity and choose deliberately. Buy cheap portability at the container and interface boundaries. Invest in real switchability only for hosted model APIs, where you will actually use it. Ignore multi-cloud unless something concrete requires it.


In three sentences

Data gravity is the only heavy form of lock-in, which is why the platform where your data already lives is usually the correct choice, while proprietary API dependencies and platform-specific orchestration are moderate and containable, and model formats and team skills are mild. The portability that costs almost nothing is worth buying — containers for your logic, open data formats, an interface between your code and any proprietary service, code in your own version control — whereas multi-cloud for its own sake, avoiding managed services and building a least-common-denominator abstraction layer all cost more than the lock-in they avoid. The one place where genuine switchability pays for itself is hosted model APIs, because the leading model changes every few months and models get deprecated, so a thin interface and a preference for gateways exposing several model families is an option you will actually exercise.


NextLesson 6: recap and FAQ →