Build the mental model
Vendor lock-in happens when you build on a provider's specific, non-portable features — a proprietary managed service, a platform-specific API, a query language extension only that vendor supports — and switching providers later becomes hard because you'd have to rebuild those parts.
Lock-in isn't automatically bad. It's a tradeoff: proprietary features are often exactly what makes a platform fast and convenient in the first place, and paying for that with reduced portability can be a completely reasonable deal, especially for a small team that has no near-term reason to switch.
Multi-cloud means deliberately using more than one provider, and some organizations adopt it for real reasons — resilience against one provider's outage, negotiating leverage on pricing, or spreading regulatory or geopolitical risk.
- Multiple consoles and billing systems to learn
- Multiple sets of credentials and permissions to secure
- Multiple monitoring setups to keep consistent
- Engineers who now need to be competent across more than one provider's quirks
Multi-cloud is a tradeoff, not automatically the right choice
For most projects, especially smaller ones without dedicated platform teams, multi-cloud is not automatically the right choice — the operational cost usually outweighs the theoretical benefit unless a specific, concrete reason demands it.
There's a middle path worth knowing about: using standard technologies where they fit — plain SQL instead of a proprietary query dialect, containers instead of a fully proprietary compute format, widely supported APIs instead of vendor-only ones — reduces lock-in risk meaningfully without paying the full operational cost of running on multiple providers at once.
- Vendor Lock-In
- The situation where building on a provider's proprietary, non-portable features makes it hard to switch to another provider later without rebuilding those parts
PORTABILITY SPECTRUM
--------------------
HIGHLY PROPRIETARY FULLY PORTABLE
|------------------------------------------------|
vendor-only APIs standard SQL, containers,
proprietary DB engine widely-supported APIs,
proprietary queue standard protocols
SINGLE PROVIDER (simple, but more locked in)
[ one console ] [ one billing ] [ one skillset ]
MULTI-CLOUD (more portable, but more complex)
[console A][console B] [billing A][billing B]
[team must know both providers' quirks]
Standard tech within ONE provider often buys most of the
portability benefit without paying multi-cloud's full cost.Connect it to a real scenario
A team building on one major cloud uses that cloud's proprietary serverless database, its proprietary message queue, and its proprietary authentication service throughout the app. It ships fast — every piece is designed to work together — but if pricing changes badly or a critical feature gets deprecated, migrating means rewriting most of the backend, not just swapping a connection string.
Compare that to a team using the same cloud but choosing standard Postgres instead of the proprietary database variant, a widely supported message-queue protocol instead of the proprietary one, and a portable authentication library instead of the cloud-specific service. They get less deep integration and maybe a bit more setup work, but switching clouds later would mean re-pointing connections rather than rewriting logic.
Neither team needs multi-cloud to make this choice — the portability gain comes from picking standard technology within a single provider, which costs far less than running two providers side by side.
Save actual multi-cloud for when a specific, named requirement — compliance, contractual redundancy, a real outage-cost calculation — justifies the added operational weight.
Multi-cloud is a tradeoff, not automatically the right choice
Do not treat multi-cloud as a default choice, especially for smaller projects — its operational complexity is worth paying for only when a specific reason justifies it.
Try the working example
function assessLockInRisk(features) {
// features: [{ name: "...", type: "proprietary" | "standard" }, ...]
const proprietary = features.filter(f => f.type === "proprietary");
const standard = features.filter(f => f.type === "standard");
const total = features.length || 1;
const score = Math.round((proprietary.length / total) * 100);
let level;
if (score >= 70) level = "high";
else if (score >= 30) level = "moderate";
else level = "low";
return {
lockInScore: score,
level,
proprietaryFeatures: proprietary.map(f => f.name),
standardFeatures: standard.map(f => f.name),
};
}
const highLockInProject = [
{ name: "proprietary serverless database", type: "proprietary" },
{ name: "proprietary message queue", type: "proprietary" },
{ name: "proprietary auth service", type: "proprietary" },
{ name: "standard object storage API", type: "standard" },
];
const lowLockInProject = [
{ name: "standard Postgres", type: "standard" },
{ name: "container-based compute", type: "standard" },
{ name: "vendor-specific CDN config", type: "proprietary" },
{ name: "standard REST API gateway", type: "standard" },
];
console.log("High lock-in project:", assessLockInRisk(highLockInProject));
console.log("Low lock-in project:", assessLockInRisk(lowLockInProject));High lock-in project: lockInScore 75, level 'high'
Low lock-in project: lockInScore 25, level 'low'5-minute try-it
Modify the feature list with different proprietary/standard ratios and see exactly when the score crosses into the "moderate" level
One important caution
Assuming any lock-in is always bad and trying to avoid every proprietary feature on principle
Assuming multi-cloud is automatically "more resilient" while ignoring the operational complexity it adds
Wikipedia: Vendor lock-in — Cloud Providers & Platforms