The Gilded Cage: How Cloud Platforms Engineer Dependency Before You Notice
In the early years of cloud adoption, the pitch was straightforward: move your infrastructure off-premises, reduce capital expenditure, and gain the flexibility to scale on demand. Flexibility was the word that appeared in every sales deck, every conference keynote, and every migration case study. What those materials did not discuss with equal enthusiasm was the other side of the flexibility equation—the gradual, systematic, and architecturally deliberate process by which cloud providers make that flexibility increasingly expensive to exercise in the direction of the exit.
This is not a conspiracy. It is a business model. The cloud providers that dominate the US market—Amazon Web Services, Google Cloud Platform, and Microsoft Azure—are rational actors building products designed to maximize customer lifetime value. Retaining customers is substantially cheaper than acquiring new ones, and the most durable form of retention is not superior service. It is architectural dependency.
How the Dependency Is Built
Cloud lock-in is rarely the result of a single dramatic decision. It accumulates incrementally, through a series of individually reasonable choices that collectively produce a system deeply entangled with a specific provider's ecosystem.
The pattern typically begins with compute. A team migrates its workloads to EC2, Cloud Run, or Azure Virtual Machines—services that, at this layer, are relatively portable. The underlying abstraction is close enough to standard Linux that migration is theoretically straightforward. Then the integrations begin.
The team adopts a managed database service—Amazon RDS, Cloud SQL, or Azure Database for PostgreSQL. Still largely portable, still using open standards. Then they add a message queue. Amazon SQS has a different API from Google Cloud Pub/Sub, which has a different API from Azure Service Bus. The application code begins to diverge from portability. Then comes the object storage layer, the serverless functions, the API gateway, the managed Kubernetes service with its provider-specific extensions, the observability tooling that only exports to the provider's native monitoring platform, and the identity and access management system woven through every other service.
At each step, the choice was sensible. Managed services reduce operational overhead. Native integrations reduce configuration complexity. Provider-specific tooling often genuinely outperforms third-party alternatives within that provider's ecosystem. The problem is not any individual choice. The problem is the cumulative architecture that those choices produce—one where the cost of migration is no longer the cost of moving compute, but the cost of rewriting every integration point in an application that has been optimized for a specific provider's service surface.
The Real Cost of Migration
Organizations that have attempted cloud migrations rarely discuss the full cost publicly. The numbers that appear in case studies tend to reflect the aspirational outcome, not the total investment. The actual migration costs that practitioners encounter are considerably more sobering.
A mid-sized SaaS company migrating from AWS to Google Cloud does not simply lift and shift its containers. It must re-evaluate every service dependency. DynamoDB tables require migration to Bigtable or Firestore, neither of which shares DynamoDB's data model. Lambda functions must be rewritten for Cloud Functions or Cloud Run, with different cold start characteristics, different timeout limits, and different runtime environment behaviors. IAM policies must be reconstructed from scratch in a completely different permission model. CloudFormation or CDK stacks must be replaced with Terraform configurations or Deployment Manager templates.
Each of these is a non-trivial engineering effort. Multiplied across a complex production system, the aggregate cost can easily reach hundreds of engineering hours—and that is before accounting for the testing, validation, and parallel-run periods required to migrate safely. For many organizations, this cost is simply prohibitive. Which is, of course, the point.
Pricing Structures That Reward Consolidation
Beyond the technical architecture of dependency, the major cloud providers employ pricing strategies that create powerful economic incentives for consolidation within a single ecosystem. Volume discounts, committed use contracts, and bundled service pricing all reduce per-unit costs as an organization deepens its relationship with a single provider.
AWS Enterprise Discount Program agreements, Google Cloud committed use discounts, and Azure Reserved Instances all function on the same principle: the more you commit, the less you pay per unit. This is rational economics, and the savings are real. But the mechanism that produces those savings is a multi-year commitment that makes the short-term economics of migration substantially worse. An organization that has committed to three years of AWS consumption at a negotiated discount faces not just the engineering cost of migration, but the financial cost of breaking or underutilizing that commitment.
Data egress pricing is a related lever that receives less attention than it deserves. All three major providers charge for data transferred out of their networks. Moving petabytes of data to a new provider is not free, and at scale, the egress costs alone can represent a significant fraction of the total migration budget. This pricing structure is not incidental—it is a direct financial penalty on the act of leaving.
Maintaining Portability Without Sacrificing Performance
The goal is not to avoid cloud providers. It is to use them deliberately, with a clear-eyed understanding of where portability is worth preserving and where the cost of provider-specific optimization is justified.
Several principles have proven durable for engineering teams navigating this tension.
Abstract at the integration layer. Applications that interact with cloud services through thin abstraction layers—interfaces that define a storage contract, a queue contract, a secret management contract—can swap provider implementations without rewriting application logic. This requires upfront design discipline but pays dividends when provider negotiations, compliance requirements, or cost structures demand a change.
Prefer open standards where the performance delta is acceptable. Kubernetes over managed proprietary container runtimes. PostgreSQL over proprietary managed databases where workload characteristics allow. OpenTelemetry over provider-native observability agents. Each of these choices preserves optionality at some cost in operational simplicity. The right tradeoff depends on the specific workload and the organization's risk tolerance.
Audit your proprietary service surface annually. Teams should maintain a clear inventory of which services in their architecture have no portable equivalent—Lambda@Edge, Spanner, Azure Cognitive Services, and similar offerings that provide genuine capabilities unavailable elsewhere. This inventory does not need to drive immediate migration. It needs to inform architectural decisions and ensure that leadership understands the dependency profile of the systems they operate.
Negotiate with migration optionality in mind. When entering committed use agreements, organizations should model the cost of early termination explicitly. Contracts that include portability provisions—the ability to reduce commitment if a migration becomes necessary—are worth negotiating for, even if they come at a slightly higher per-unit price.
The Honest Architecture Conversation
Cloud providers offer genuine value. The managed services, global infrastructure, and operational tooling available from AWS, Google Cloud, and Azure represent capabilities that would be prohibitively expensive to replicate independently. The argument here is not against using them. It is against using them without understanding the structural incentives that shape how they are designed and priced.
Every architectural decision that deepens integration with a proprietary cloud service is a decision that shifts leverage from the customer to the provider. That shift is not always wrong. But it should always be intentional.
The teams that maintain real infrastructure flexibility are not the ones who avoided cloud providers. They are the ones who understood exactly what they were trading away—and decided it was worth it.