Separate containers from operating models first
Explanations like "small teams use PaaS and move to Kubernetes as the company grows" are of little help in an actual decision. Two teams of the same size can carry completely different infrastructure responsibilities, depending on whether they can operate Linux, networking, and incident response themselves or are focused on application development.
The first question in choosing compute is not "how big a technology do we need". It is "which control is absolutely required, and who will keep owning the recurring operational work created by obtaining that control".
VM, PaaS, Managed Container, and Kubernetes are not stages of maturity. Within one company, an old business system can sit on VMs, a public API on Managed Container, and other platform workloads on Kubernetes. The most suitable model is the one that, among the candidates satisfying the required control, fits inside the team's Complexity Budget.
A Container is a way to package and run an application; it is not in itself an operating responsibility model. A PaaS can accept Container Image deployments, and Kubernetes runs Containers too. Conversely, you can run Docker yourself on a single VM. The four models compared in this article therefore follow the definitions below.
The typical form of Managed Container is a service such as Cloud Run or Azure Container Apps, which deploys Containers without you operating a Kubernetes Cluster. Cloud Run's current documentation also describes a structure that runs Services, Jobs, and Worker Pools without creating a separate Cluster or managing Infrastructure. With Kubernetes, even when Managed Kubernetes hands the Control Plane to the Provider, the Application and Workload Policy do not disappear automatically.[2] In other words, "we want to use Containers" is not by itself a reason to need Kubernetes.
- VM
- A model in which the team directly manages most of the stack starting from the Guest OS.
- PaaS
- A model in which you upload source or an Application Artifact and the Provider manages most of the Platform layer, including the OS and Runtime.
- Managed Container
- A model that keeps the freedom of a Container Image but hands Cluster and Host operations to the Provider. The typical form deploys Containers without operating a Kubernetes Cluster yourself.
- Kubernetes
- An operating model that controls Scheduling, Service Discovery, Resource Policy, Rollout, Networking, and Storage Integration for Container Workloads through the Kubernetes API.
Turn compute selection into a Complexity Budget
When deciding on a Compute Operating Model, three things must be looked at together.
The first is Required Control: how much control is really needed. An application that needs only standard HTTP Routing and a few environment variables does not demand the same level of control as a platform that needs a specific Network Topology, GPU Placement, Privileged Workloads, or fine-grained Service-to-Service Policy. If the platform's abstraction makes the actual requirement impossible to implement, you have to take a lower level of control.
The second is Sustainable Operations: can you keep operating that control. Being able to install something once is different from being able to keep operating it in Production. There must be an Owner who will keep handling OS Patches, Certificates, Image Updates, Node replacement, Runtime Upgrades, Autoscaling, Network Policy, Logging, Alerts, Backups, and incident response going forward.[3] An operational responsibility without an Owner cannot be considered part of the team's Complexity Budget.
The third is Acceptable Exit Cost: can you leave. Easy adoption does not always mean easy exit. You have to look separately at whether moving only the Application Runtime is enough, or whether Deployment configuration, IAM, Network, Storage, Managed Database, Observability, and CI/CD all have to be rebuilt.
Put simply, it looks like this. Eligible Operating Model = satisfies the required control + recurring operational responsibility does not exceed the team's capability + Exit Cost is within an acceptable range. If several candidates pass these conditions, there is no reason to pick the most "modern" one. The one with less complexity to operate on an ongoing basis becomes the default candidate.
From service architecture to operating standards — Design networks and servers together with deployment paths, access controls and backup policies.
Compute Operating Model Decision Matrix
The table below is a Matrix for comparing operational responsibility, not the relative merits of product features.
What deserves attention in this Matrix is that the operating burden in the Kubernetes column is not a single value. The Kubernetes documentation itself advises deciding first whether to operate a Production Cluster yourself or how much to delegate to a Provider.[6] Today there are also forms such as GKE Autopilot and EKS Auto Mode, in which the Provider takes over much of the Worker Nodes and Infrastructure Operations.
Conversely, a managed service does not remove Application responsibility either. In Microsoft's Shared Responsibility Model, with IaaS the customer manages the VM, OS, and Application, and with PaaS the OS responsibility shifts toward the Provider, but data, Identity, Configuration, and Application-level responsibility remain with the customer.[4]
Decision axis | VM | PaaS | Managed Container | Kubernetes |
|---|---|---|---|---|
| Number of Services | Few or tightly coupled services run simply. As they multiply, standardizing deployment and configuration becomes a separate task | Good for running several standard Web/API-centric Apps independently | Fits several independently deployed Container Services and Jobs well | Value grows when many Workloads need common Scheduling, Policy, and a Platform API |
| Stateful / Stateless | You control even Local State directly, but Backup, HA, and Migration responsibility grows with it | Persistent state is usually separated into an external Managed DB or Storage | Combining Stateless execution with external State is simple | Stateful Workloads are possible, but StorageClass, Backup, and Upgrade operations must also be considered |
| Traffic Variability | You design the Capacity and Scaling structure yourself | Uses the platform's built-in Scaling | Many services favor Request- and Event-based automatic scale-out | Pod and Node Scaling can be designed in fine detail, but the configuration and operational responsibility come with it |
| Deployment Frequency | You build the Pipeline, Artifact, and Rollback system yourself | Easy to use the platform's standard Deployment path | Image Revision-based deployment and Traffic Control are the norm | Strong standardization such as Rolling Update and GitOps is possible, but the Platform operating surface grows |
| Isolation | You configure the OS boundary per VM yourself | You choose within the isolation model the Provider offers | Uses Platform isolation at the Container Instance or Environment level | Many boundaries such as Namespace, Node, and Cluster can be designed, but separate policy is needed to meet the required level |
| Networking | High control down to the OS, Firewall, and Routes | The most Opinionated. Simple only when you fit the standard network path | Intermediate control such as VPC Integration, Ingress, and Egress | High control and a high operating surface together, via CNI, NetworkPolicy, Ingress/Gateway, and Service Mesh |
| Scaling | You design VM or Process Scale yourself | Centered on Platform Scale features | Delegates Instance/Request/Event Scaling largely to the Provider | Can be configured in very fine detail based on Pod, Node, and Custom Metrics |
| Portability | The OS and Application themselves may move easily, but Network, Data, and Managed Services are separate matters | Check dependencies on the Platform Runtime, Build, and Configuration | Container Image portability can be high, but the surrounding Platform configuration is a separate matter | The Kubernetes API provides a common base, but Provider Integration such as Storage, Load Balancer, and IAM is separate |
| Platform Operations | The team manages the OS, Runtime, Patches, Agents, and more | Low | Low to medium | Medium to high. With Managed/Auto Mode, the Node operating burden can drop substantially |
| Observability | You design even the Agents and collection paths yourself | Uses the default Platform Telemetry. Application observability remains the team's responsibility | Uses Platform Log and Metric Integration. Application Traces and SLIs are separate | The observability scope widens beyond the Application to the Cluster, Pods, Nodes, and Control Surface |
| Security Responsibility | On top of the Application, large responsibility for OS Patches, Host, and Network | OS responsibility shifts to the Provider, but Code, Data, Identity, and Configuration remain the team's | The team is responsible for Image, Application, IAM, Secrets, and Configuration | Kubernetes operating responsibilities such as RBAC, Pod Security, Workload Identity, and Network Policy may be added on top of the Application |
| On-call Capability | Requires the ability to handle both Host and Application failures | Platform failures can be escalated to the Provider. Responsibility for Application failures remains | Response centers on Container Workloads and their Dependencies | Requires an operating system that responds down to the Cluster/Workload Layer. Even in Auto Mode, Application responsibility remains |
| Regulatory / Isolation | Easy to design fine-grained structures such as Dedicated VMs and Networks, but you carry compliance responsibility yourself | First verify that the Platform provides the required controls | Verify the Isolation, Region, and Network conditions of the specific Service | Fine-grained policy can be implemented, but using Kubernetes does not by itself prove regulatory compliance |
| Team Capability | Linux, Network, Patch, and Automation operating skills matter | Centered on Application operating skills | Requires an understanding of Containers, Images, and the Cloud Runtime | Requires Kubernetes operations, Networking, Resource, Security, Upgrade, and Incident capabilities |
| Exit Cost | Beyond moving the OS/App, check the cost of rebuilding Data, Network, and Automation | Check dependencies on the Runtime, Build, and Platform API | Beyond the Image, check dependencies on IAM, Scaling, Network, and Managed Services | Beyond Manifests, check dependencies on CSI, Load Balancer, IAM, Observability, and Data |
VM is the choice to control everything down to the OS
The advantage of a VM is simple. You decide what to install, which Processes to run, and how to configure the Network and File System. For old Applications, unusual System Packages, specific Daemons, conventional Stateful Services, and Workloads where OS-level settings matter, this control can actually be the simplest solution.
The problem is that operational responsibility comes back along with control. Who handles it when OS security updates fall behind, when to upgrade the Runtime, who responds when a Disk fills up, and how to bring a server back when it goes down are all the team's problems.
So a better question than "traffic is small, so VM" is this. Does this Workload actually need OS control, and is there someone to keep operating that OS? If either answer is no, the freedom of a VM can become an unused responsibility rather than an advantage.
PaaS is closer to a contract that limits responsibility
The biggest advantage of PaaS is not the smaller number of Servers. It is the smaller number of Layers the team is responsible for. Azure's current Shared Responsibility documentation also shows a structure in which, on PaaS, the Provider manages the OS and Platform Services while users focus more on the Application, Data, Identity, and Configuration.[4]
If a typical Web Application, REST API, or Background Process works well enough within the Runtime and Deployment Model the Platform supports, this constraint may not be a loss. On the contrary, "you cannot log into the OS and do whatever you want" acts as a Guardrail against operational complexity.
Conversely, when requirements outside the Platform Contract keep recurring, such as specific System Packages, Runtime Extensions, special Networking, long-running Processes, or unsupported Protocols, the cost of forcing workarounds around PaaS grows. What is needed then is not Kubernetes right away, but checking whether one more level of Application Runtime control is required.
Managed Container is a compromise between freedom and the operating boundary
Managed Container takes this middle ground. The team can include the Runtime and System Dependencies in the Container Image it builds, but hands to the Provider which VM it is placed on, how the Host OS is patched, and how the Cluster Control Plane is operated.
Today Cloud Run supports not only HTTP Services but also Batch Jobs and always-running Worker Pools. A Service can automatically add and remove Instances according to load, and minimum and maximum Instances or Manual Scaling can be configured when needed. Azure Container Apps likewise offers a model that deploys Container Applications without operating Servers or Container Orchestration Infrastructure yourself and scales them based on HTTP, Event, CPU, and Memory conditions.
So if you need an Image with more freedom than a standard PaaS Runtime but have no interest in Nodes, and you want to deploy APIs, Workers, and Jobs independently while leaving Traffic changes to the Platform, Managed Container becomes a strong candidate.
But the team's responsibility does not disappear here either. A bad Container Image, Secrets, IAM, an Application Memory Leak, DB Connection exhaustion, or a wrongly set maximum Instance count are not things the Provider fixes for you. Platform Operations have been reduced; Application Operations have not been removed.
Kubernetes becomes necessary not when traffic grows
One of the weakest reasons to adopt Kubernetes is "it will probably grow later". Rapidly increasing Traffic is not by itself a reason to need Kubernetes. Managed Container Platforms can also scale Instances according to Traffic or Events.
The number of services is not a standalone criterion either. If ten APIs all use the same deployment, Network, and Security patterns, they may well run fine on Managed Container. Conversely, even with few services, if you must directly control Workload Scheduling, special Hardware, fine-grained Network Policy, Operators or CRDs from the Kubernetes ecosystem, or an organization-wide Deployment Policy, the Kubernetes API can be meaningful. The reason to consider Kubernetes generally arises when the same operational problem has to be solved repeatedly across many Workloads and it is worth standardizing that problem with a Platform API and Policy.
At the same time, the operating surface that Production Kubernetes adds must not be ignored. The Kubernetes documentation explains that in a Production environment, not only Control Plane availability but also Worker Nodes, User Access, and Resource Policy must be handled separately.[7] Managed Kubernetes hands some of this to the Provider, but even in GKE's current Shared Responsibility documentation, substantial responsibility such as Application Code, Build Files, Container Images, Data, IAM/RBAC, Pods and Workloads, and Monitoring and Incident Response remains with the user.
"It is Managed Kubernetes, so we do not need to know Cluster operations" is not accurate either. Models such as EKS Auto Mode and GKE Autopilot, which let you delegate more of Nodes, Patches, and Scaling, certainly lower the operating burden. But the Provider does not take ownership of the Resources, Policy, Identity, Deployment, and failure judgment of the Workloads that use the Kubernetes API.
Write down actual operating capability, not headcount
The question "we have five developers, can we do Kubernetes?" alone cannot be answered. A team in which one of the five can continuously own Production Kubernetes, Networking, and Incident Response has a completely different Complexity Budget from a team in which all five work mainly on Product Feature development.
It is therefore better to write down on a Complexity Budget Card whether there is an actual Owner per role. On the card, record the person responsible for OS/Host Patches, Runtime/Base Image Upgrades, Deployment/Rollback, Network/Access Policy, Secrets/Identity, and Scaling policy. Next, record the person responsible for Application Observability, Platform Observability, Backup/Restore, and Platform Upgrades, along with the Incident Commander, night and holiday Escalation, and Provider Support Escalation. Finally, record whether a Runbook exists for each item and the date of the most recent actual recovery or incident drill.
Filling in names alone is not enough. Only when the time and authority to carry out the work, the means of observation, and the Runbook and Escalation path are all in place can it be counted as actual operating capability.[5] This is why Kubernetes can be reasonable for a team of three, and why an organization with dozens of developers may still be unsuited to operating Kubernetes if it has no Platform Ownership.
Map dependencies and rehearse the transition — Group dependent systems, rehearse the move and agree rollback conditions before cutover.
Do not choose Kubernetes just because it is Stateful
Kubernetes can run Stateful Workloads with StatefulSets and Persistent Volumes. That does not automatically make putting a Database inside Kubernetes the better operating model. Operating Persistent Storage means handling Volume Provisioning, Availability Zones, Backup, Restore, Upgrades, and Failure Recovery together.
Kubernetes StorageClasses also use a provisioner that creates the actual Storage and Provider-specific Parameters. In the official documentation's examples for AWS EBS, EFS, Azure, vSphere, and others, different Storage Integrations sit behind the same Kubernetes API.[2]
For a small team, keeping Application Compute on PaaS or Managed Container and leaving State to a Managed Database may demand a lower Complexity Budget. Conversely, if Data Locality or Storage Control requires you to operate it yourself, VM or Kubernetes can be candidates. The single word Stateful does not decide the answer.
Portability is not judged by a Container Image alone
Using Containers lets you package the Application Runtime as a consistent Image, which helps Compute mobility. Kubernetes also provides a common API that makes some operational expressions such as Deployments and Services easier to reuse across environments. But this must not be stretched into "Kubernetes eliminates Vendor Lock-in".
For example, a Kubernetes Service of type LoadBalancer provides the common concept of an external Load Balancer, but the actual implementation is handled by the Cloud Provider and may involve Provider-specific Annotations and constraints. Storage likewise varies with the CSI Provisioner, StorageClass Parameters, and the actual Storage Backend.[2]
The real Exit Cost must be calculated with all of the following together. Exit Cost is the sum of the eight components below. This cost is not zero because it is a VM, not necessarily large because it is PaaS, and not automatically small because it is Kubernetes. Compute Portability and System Exit Cost are different metrics.
- Exit Cost
- Sum of the eight cost components below.
- Application changes
- Include in the total cost.
- Runtime / deployment configuration changes
- Include in the total cost.
- Network / security reconfiguration
- Include in the total cost.
- Data movement
- Include in the total cost.
- IAM / secret reconfiguration
- Include in the total cost.
- CI/CD changes
- Include in the total cost.
- Observability changes
- Include in the total cost.
- Operational procedure and training changes
- Include in the total cost.
Regulation and isolation are not solved by a Technology name
You cannot conclude "PaaS is out, it has to be Kubernetes" because there is regulation, nor conversely "it is a Managed Service, so the Provider is responsible for security". What has to be checked is the actual requirement.
First establish whether Data must be kept in a specific Region, whether a Dedicated Host is needed, whether the Network path must be controlled, whether administrator access must be audited, and what level of isolation between Workloads is required. Then compare whether each service actually provides those controls.[8]
Kubernetes is a tool that can implement many controls, but the name Kubernetes is not itself Compliance Evidence. Likewise, a Managed Service does not remove the customer's Data, Identity, and Application responsibility just because the Provider is responsible for the Infrastructure.
This order makes the actual choice simplest
If a Workload Placement Card was produced in the article to read first, you can now narrow down in the following order. That article sets the boundary of confirming workloads and constraints first, deciding the Operating Model, and then comparing Vendors.
First, write down the control the Workload absolutely requires. Keep only the items whose absence would disqualify a candidate, such as OS access, a special Runtime, Network, Isolation, GPU, or Deployment Policy. Second, write down the recurring operational work that stays with the team under each model. Confirm the Owner of Patches, Upgrades, Scaling, Network, Observability, Backup, and Incident Response. Third, remove candidates that cannot provide the required control. Do not keep a candidate alive by forcing workarounds around Platform constraints.
Fourth, remove candidates that exceed the team's Complexity Budget. Distinguish the plan that "we can learn it" from the current ability to be responsible for Production. Fifth, among the remaining candidates, pick the model with the lowest Exit Cost and operational complexity. Sixth, compare Vendors and products last. Even within the same Operating Model, Region, Networking, Scaling, Support, and the actual responsibility boundary differ.
This order does not mean starting with PaaS and promoting step by step up to Kubernetes. VM may be right from the start, staying on PaaS for a long time may be reasonable, and using Managed Container and Kubernetes at the same time is also possible.
Applying Workloads makes the differences clearer
The table below shows the result of applying the four models to a few representative situations. Here too, the number of services and the size of the company do not appear as direct selection criteria. Those numbers are only one of many inputs that create operational complexity.
Situation | Candidate to look at first | Reason | Additional checks |
|---|---|---|---|
| Public Web API + Worker + external Managed DB, high Traffic variability, standard HTTP | PaaS / Managed Container | Application deployment and Autoscaling matter more than the OS or Cluster | PaaS Runtime constraints, whether Containers are needed, Cold Start, DB Connections |
| Old business Application that needs specific Daemons, System Packages, and OS settings | VM | OS control is a genuine requirement | Owners for Patch, Backup, Failover, and Deployment automation |
| Several APIs, Workers, and Batch jobs deployed independently, but Network and Scheduling needs are standard | Managed Container / PaaS | Independent deployment is needed, but Cluster Control may not be | Per-Service Scaling, IAM, Cost, Platform Limits |
| Several teams and Workloads share a common Platform and need fine-grained Scheduling, Policy, and Network Control | Kubernetes | It is worth turning recurring operational problems into a common API and Policy | Platform Owner, Upgrade, RBAC, Network, Observability, On-call |
| Specific regulations impose dedicated isolation, Network, and Audit conditions | VM / Managed Platform / Kubernetes are all possible depending on the requirements | The actual control requirements, not the Technology name, decide the candidates | Regulation text, Provider Architecture, Audit Scope |
The highest abstraction is not the best
The lowest abstraction is not the most powerful, and the highest abstraction is not the best. A VM offers high freedom, but to keep that freedom you must operate the OS. PaaS hands many decisions to the Platform, but in return you must accept the Platform Contract. Managed Container offers a middle choice between Application Runtime freedom and delegating Platform operations.
Kubernetes provides high control over Scheduling, Policy, Networking, and Platform Extensions, but brings with it responsibility for operating that API and its Workloads.[1] The evolution of Managed Kubernetes can reduce that burden considerably, but the responsibility boundary does not disappear entirely.
The question a small development team needs is not "have we grown enough to use Kubernetes?". It is what level of control the current Workload requires, and whether the team can keep carrying the recurring operational responsibility created by obtaining that control. Write down that answer first, and VM, PaaS, Managed Container, and Kubernetes start to look like different responsibility contracts rather than an order of maturity. And from that point, choosing compute becomes far simpler.



