Skip to content

A Vendor Lock-In Checklist, Component by Component

10 min read · updated August 11, 2026

“How locked in are we?” has no answer, because lock-in is not a property of a vendor. It is a property of each component separately, and in a typical stack the numbers differ by an order of magnitude between the cheapest layer to move and the most expensive. Score them individually and you get a work list.

The five questions

Ask these of every component, and score each 0 (no cost) to 2 (severe) for a component total out of 10.

  1. Is there an alternative that speaks the same interface? Not “is there a competitor” — is there one you could call without rewriting your call sites.
  2. Can the state be exported in a usable form? Usable meaning the replacement can consume it, not merely that a file downloads.
  3. If it cannot be exported, can it be rebuilt from inputs you hold? And what does the rebuild cost in compute and wall-clock?
  4. Does the swap change behaviour, or only plumbing? A component whose replacement produces byte-identical results is a deployment. One that produces merely similar results is a re-verification project.
  5. How much downstream is tuned to this component? Every threshold, prompt and test fitted against it has to be refitted.

Question five is the one that dominates real migrations, and it is the one nobody asks. The work is rarely in the swap; it is in proving the system still behaves.

Model calls and the SDK

Usually the lowest score in the stack, which is the opposite of the popular intuition. The interface is a small number of concepts — messages, a system instruction, sampling parameters, tool definitions, a stream — and every major API expresses all of them. An adapter with one method per concept is a few hundred lines.

What raises the score is not the API surface but three specific things. First, if provider-specific request objects have leaked into your business logic, question one becomes a rewrite rather than an adapter. Second, behaviour: the same prompt on a different family produces different formatting, different refusal boundaries and different tool call rates, so question four scores 2 nearly always. Third, anything you use that the other side lacks — a seed parameter, a specific structured-output guarantee, a caching mechanism, log probabilities — is a capability you must shim or drop.

The mitigation is boring and effective: one internal request type, one adapter per provider, nothing provider-shaped above that line. See writing provider-agnostic AI code for how that layer is structured.

Embeddings, vector store and retrieval

Almost always the highest score in the stack, and worth splitting into three components because they lock in independently.

The embedding model scores near 10. There is no alternative that produces compatible vectors — that is not a gap in the market, it is what an embedding is. Export gives you floats that are meaningless without the model. Rebuilding means re-embedding the entire corpus, at a cost proportional to your total document tokens. Behaviour changes, because retrieval ordering changes. And everything downstream is tuned to it: similarity thresholds, top-k, reranker cutoffs, any “no good match” rule.

The vector database scores far lower than people expect, if and only if you can re-embed. Once you accept a re-embed, the store is a commodity: you are writing vectors and metadata into a different index. The lock-in is in features you built on — hybrid search behaviour, filter semantics, a particular index type’s recall characteristics — not in the storage.

The chunking configuration scores mid, and is invisible on most checklists. If a managed service chose your boundaries, you cannot reproduce them, and retrieval quality is sensitive to them. If you own the splitter, this scores near zero.

Orchestration and prompts

Prompts score low on export and high on behaviour. The text moves for free; what it does on the other side is a separate project, which is why a prompt registry with versions and an evaluation set attached is worth more than the prompts themselves.

Orchestration frameworks vary enormously. A framework used as a thin convenience over HTTP calls scores 2 or 3. A framework whose graph, state machine and persistence you have adopted wholesale scores 8 or more, because question two has no answer — the workflow definition exports only as a description of itself and there is no other runtime that consumes it. This is a rewrite priced in engineer-days, and it is the line item most often left out of migration estimates.

The distinction to watch for is whether the framework holds state. A library you call is replaceable. A runtime that calls you, persists checkpoints and owns your retry semantics is not.

Fine-tunes, evals and observability

Fine-tunes score high on export — the trained artifact is usually not downloadable and is bound to a base model you cannot take elsewhere — but score better than embeddings on rebuild, because the training file is text you hold. The real cost is that the rebuild is a new experiment on a different base, not a transfer; translating a fine-tune between providers covers what survives.

Evaluation suites should score near zero and often do not. Cases are text and belong in your repository. If they live only inside a vendor’s evaluation product, you have put the instrument you would use to verify a migration inside the thing you are migrating away from, which is the single worst placement in the whole stack.

Observability and cost data score low on switching and high on loss. Pointing traces at a different backend is straightforward; carrying twelve months of history across is usually not possible, and that history is your only baseline for judging whether the new stack is worse.

Reading the scores

The output is not a total. Summing across components produces a number that means nothing, because the components are not comparable in size. Read it three ways instead.

  • Highest single score is your critical path. It sets the minimum duration of any migration, and everything else can be parallelised against it.
  • Any component scoring 2 on question five is where the effort actually goes, regardless of its total. Re-verification dominates.
  • Any component scoring 2 on question two with 0 on question three — cannot export, cannot rebuild — is not a migration item at all. It is a loss, and it should be recorded as one now so that nobody plans around recovering it.

Rerun the scoring when the stack changes, not when a migration is proposed. The point of doing it early is that most of the fixes — keeping training files, owning the splitter, holding evaluation cases in git — cost nothing while everything is working and cannot be done retroactively. The argument for why the scores come out this uneven is in which parts of an AI stack are actually portable.