SOV 10. How do you preserve the ability to move the workload elsewhere?
Last updated on
Reversibility is a sovereignty property in a specific sense: a dependency you cannot leave is a dependency that decides your terms. That matters for regulatory requirements that ask for an exit capability, and it matters for the ordinary commercial reason that an alternative you could actually take is what makes a negotiation a negotiation.
The naive version of this question is to avoid managed services, which trades a large certain cost for a small uncertain one and usually produces a worse system. The useful version is to know what each dependency costs to leave, and to accept that cost deliberately where the service is worth it.
Best practices
Section titled “Best practices”SOV 10.1Prefer open interfaces where the alternative is equivalentSOV 10.2Keep data in portable formats and know how to get it outSOV 10.3Separate what is portable from what is provider-specificSOV 10.4Price the exit for each dependency and accept it explicitly
SOV 10.1 Prefer open interfaces where the alternative is equivalent
Section titled “SOV 10.1 Prefer open interfaces where the alternative is equivalent”Risk if not established: Medium
An interface with several independent implementations is one you can leave without rewriting. Where a standards-based option is equivalent in capability, taking it costs nothing and preserves the option.
The qualifier matters. Where the proprietary option is genuinely better, taking the open one to preserve portability is paying a permanent cost for a contingency, and that trade should be made consciously rather than as a rule.
The interfaces that carry the most weight are the ones the whole workload sits on: the container orchestrator, the object storage protocol, the database engine, the application runtime, and the messaging protocol. A portable choice at those layers preserves far more than a portable choice at the edges.
Distinguish the interface from the implementation. A managed service exposing a standard interface is portable at the interface even though the operational surface differs, and that is usually the practical middle: the provider operates it, and your code does not know which one.
On STACKIT. The platform is built on this pattern at nearly every layer, which is what makes the practice available rather than aspirational.
Object Storage is S3-compatible, including lifecycle configuration and versioning through the same API, so the storage layer of an application is expressed in an interface with many implementations.
Kubernetes Engine runs upstream Kubernetes, and Cloud Foundry is an open platform, so the workload definition is portable at the level that matters most.
The managed data services run open-source engines, for example PostgreSQL and the key-value store , which means the wire protocol and the query language your application depends on are not provider-specific.
The layer that is provider-specific is provisioning, which the Terraform
provider and
the API express. That is the correct
place for it to sit, since it is the layer SOV 10.3 asks you to separate anyway.
Tradeoffs. Performance Efficiency and Operational Excellence. A standard interface sometimes lags a proprietary one in capability, and portability is worth less than a feature the workload genuinely needs.
Verify. For each major interface your workload depends on, how many independent implementations exist? Which of your dependencies has exactly one?
SOV 10.2 Keep data in portable formats and know how to get it out
Section titled “SOV 10.2 Keep data in portable formats and know how to get it out”Risk if not established: Medium
Data is the part of a migration that dominates. Code can be rewritten on a schedule; a large data set in a format only one system reads is what makes an exit a project rather than a decision.
Two properties are needed and they are separable. The format has to be readable by something else, meaning a documented schema or an open format rather than an internal representation. The export path has to exist and be usable at your actual data volume.
The second is where plans fail. An export that works for a gigabyte and takes weeks for the real
data set is not an export path, and nobody discovers that until they try it, which is why SOV 11
asks for the test.
Include the parts that are not the primary store: object metadata, access policies, schema definitions, configuration and the historical records you are obliged to retain. A migration that moves the rows and leaves the retention history behind has not moved the obligation.
Know the shape of the constraint as well as the mechanism. Volume, time and cost are all real limits, and egress at scale takes long enough that it belongs in a plan rather than in an assumption.
On STACKIT. Because the managed engines are open-source, their native export mechanisms are the export path, and those are widely understood tools rather than proprietary ones. Object Storage’s S3 compatibility means the standard ecosystem of transfer tooling applies to the object layer.
What the platform does not remove is the physics. Moving a large data set takes the time it takes, and that figure is a property of your data rather than of the platform, which makes measuring it the only way to know it.
Tradeoffs. Performance Efficiency. A portable format is sometimes less efficient than a proprietary one, which is a real cost paid continuously against a contingency.
Verify. For your largest data set, what is the export path and how long would exporting it take? Has anybody measured that rather than estimated it?
SOV 10.3 Separate what is portable from what is provider-specific
Section titled “SOV 10.3 Separate what is portable from what is provider-specific”Risk if not established: Medium
Every workload has provider-specific parts and that is fine. What decides the cost of an exit is whether those parts are identifiable or spread through the application.
Draw the boundary deliberately. Business logic should not know which provider it runs on. Provider-specific concerns belong behind an interface, in a configuration layer, or in the infrastructure definitions rather than in the code paths that implement the product.
The recurring leak is a provider SDK imported directly into business logic. It works, it is convenient, and it means the provider dependency is now distributed across the codebase rather than concentrated where it can be replaced.
Infrastructure definitions are the honest exception. They are provider-specific by nature and rewriting them is a known, bounded cost, which is a much better position than a diffuse dependency nobody can enumerate.
Resist over-abstraction. A layer designed to support a hypothetical second provider costs complexity now for a benefit that usually never arrives, and it frequently reduces to the intersection of both providers’ capabilities. Concentrating the dependency is the goal rather than hiding it.
On STACKIT. The natural boundary is that the workload interfaces are open and the provisioning layer is not. Your application speaks Kubernetes, S3, PostgreSQL and HTTP; your Terraform definitions and any use of the SDKs speak STACKIT.
That split is the one to preserve, and it happens by default unless a platform SDK is used inside the application rather than at its edges.
Tradeoffs. Operational Excellence. An abstraction layer is code to maintain and can obscure useful provider capabilities, which is why the goal is concentration rather than a full abstraction.
Verify. How many files in your application import a provider-specific SDK? Could you list every provider-specific component from memory?
SOV 10.4 Price the exit for each dependency and accept it explicitly
Section titled “SOV 10.4 Price the exit for each dependency and accept it explicitly”Risk if not established: Medium
The point of this question is not to have no lock-in. It is to know what each dependency would cost to leave, so that the decision to take it is a decision.
Estimate three things per significant dependency: the engineering effort to replace it, the data migration cost and duration, and the elapsed time before the workload could run elsewhere. Rough figures are enough, because the useful output is the ordering rather than the number.
Then accept it. A managed service that saves substantial operational work and would cost three months to leave is frequently a good trade, and recording that reasoning is what makes it defensible later. The failure is not the dependency; it is discovering its cost during the conversation where it matters.
Watch for the ones that are expensive and low-value: a proprietary component that saved a week of work and now takes months to leave. Those are worth removing while the removal is cheap.
Revisit when circumstances change. A dependency taken when the workload was small can become the most expensive thing in the estate as the data grows, and nothing signals that moment.
On STACKIT. Because most layers are open, the list of genuinely expensive exits is usually short, and that is the point of making it: a short list is one an organization can actually act on.
Where the answer for a given dependency is that leaving would be expensive, that is information
for SOV 11 and for the tier, rather than a reason to avoid the service.
Tradeoffs. None beyond the effort. Pricing an exit costs an afternoon per significant dependency and turns a vague anxiety into a list.
Verify. For your three most significant provider dependencies, what would each cost to replace? Where is that written down?
Related
Section titled “Related”SOV 11Exit plan, which tests what this makes possibleSOV 6Jurisdictional chain, whose changes this decides the cost of responding toREL 5Resilient interactions, the reliability view of the same dependenciesCOST 1.2Managed versus self-operated, the same trade priced financiallySOV 1Tier, which sets how strictly this binds