Core Cloud Architecture · Part 3 of 13
Compute Options
Several ways to run the same code, trading control for operational simplicity.
You have several options for running your code in the cloud, and they differ in how much of the surrounding machinery you manage yourself: moving from a virtual machine toward a serverless function hands more of the operating system, the scaling, and the infrastructure to the provider.
Virtual machines
A virtual machine (VM) is a full, isolated operating system you provision, running on the provider's physical hardware alongside other customers' VMs. You choose the OS, install what you want on it, and are responsible for patching, scaling, and everything else an operating system needs. VMs offer the most control of any option, and the most operational responsibility to go with it.
Containers
A container packages an application together with its dependencies into one portable unit, run by a container runtime rather than as a full separate operating system. Containers share the host OS kernel, so they start in seconds rather than minutes, and the same container image runs the same way on a laptop, in automated testing, and in production. Containers can run on your own VMs, on a managed container service, or on Kubernetes (below).
MicroVMs
A microVM (Firecracker, built and open-sourced by AWS, is the best-known example) gives each workload its own minimal virtual machine with its own kernel, where a plain container shares the host's. A kernel bug in one workload doesn't expose the others, because an attacker would also have to break out of the hypervisor. A microVM boots in a fraction of a second, where a full VM takes tens of seconds, which makes it fast enough to sit behind a serverless function while giving many tenants VM-grade isolation on shared hardware. The idea appears differently on each cloud. AWS Lambda and Fargate run on Firecracker. Google Cloud Run's second-generation execution environment is a microVM, while its first generation uses gVisor, a user-space sandbox that emulates system calls instead of running a separate kernel. On Azure, AKS pod sandboxing runs each pod in a lightweight VM with its own kernel, built on Kata Containers and the open-source Cloud Hypervisor, and Azure Container Instances isolates each container group at the hypervisor level.
Serverless functions
A serverless function (AWS Lambda, Cloud Run functions, Azure Functions) runs a single function in response to an event (an HTTP request, a message on a queue, a file upload) and the provider handles everything about where and how it executes. You write a function; you never provision a server, patch an OS, or explicitly manage scaling. Billing is typically per invocation and per unit of execution time, down to fractions of a second, so an idle function costs nothing to keep around. The trade-off is less control over the runtime environment, tighter limits (maximum execution time, memory, available languages and versions), and cold starts.
Serverless containers
A serverless container platform (Google Cloud Run, AWS Fargate, Azure Container Apps) runs a container image without you provisioning or managing the underlying servers, combining a container's portability with a serverless function's operational simplicity.
Kubernetes
Kubernetes is a container orchestration system: it schedules containers across a cluster of machines, restarts ones that fail, scales them, manages networking between them, and rolls out updates gradually. The execution unit is still a container, but Kubernetes has the most moving parts of any option here (nodes, pods, deployments, services, ingress, and others), whether run yourself or through a managed offering (Amazon EKS, Google GKE, Azure AKS) that handles the control plane for you.
Choosing between them
| Option | Operational burden | Portability | Cost model | Control | Isolation |
|---|---|---|---|---|---|
| Virtual machines | High | Moderate | Pay for capacity | Highest | Highest |
| Containers (self-managed) | Moderate to high | High | Pay for the VMs | High | Lower |
| Serverless containers | Low | High | Pay while running | Moderate | High |
| Serverless functions | Lowest | Low | Pay per invocation | Lowest | High |
| Kubernetes | Highest | High | Pay for cluster capacity | Highest | Lower |
Equivalent services across the three major clouds
| Concept | AWS | GCP | Azure |
|---|---|---|---|
| Virtual machines | EC2 | Compute Engine | Virtual Machines |
| Serverless functions | Lambda | Cloud Run functions | Azure Functions |
| Managed containers | ECS | Cloud Run | Container Apps |
| Serverless containers | Fargate | Cloud Run | Container Apps |
| Managed Kubernetes | EKS | GKE | AKS |
Does this startup need Kubernetes?
Kubernetes often gets adopted before it's needed, because it looks like the serious choice. A correctly run cluster costs ongoing attention from people who could be building the product.
Some reasons to adopt it:
- Multiple teams need independent deploy cadences across many services, with enough of them that a serverless-container platform's simpler model has started to feel limiting.
- A multi-cloud or on-prem portability requirement: a current commitment to run the same workload across more than one environment.
- Workloads that don't fit serverless or managed containers: specialized scheduling needs (GPU pools, custom networking, fine-grained control over how pods are placed) that a simpler managed platform can't express.
The main trade-off across these options is how much you operate yourself against how much control you keep. Portability is a separate axis: serverless functions are the least portable and containers on Kubernetes the most. Where a startup should sit depends on the stage-and-risk framing from Startup Stages and Risks. A pre-seed company optimizing for how fast it can test whether anyone wants the product should default to the lowest operational burden.