Choosing compute — Kubernetes vs Serverless¶
The choice cascades through every Chiron recipe. Pick once per service you're building; the reusable Terraform + Helm baseline branches on that choice.
Per-provider names¶
Whatever cloud you're on, the two options exist:
| Choice | Azure | GCP | AWS |
|---|---|---|---|
| Kubernetes | Azure Kubernetes Service (AKS) | Google Kubernetes Engine (GKE) | Elastic Kubernetes Service (EKS) |
| Serverless (container) | Container Apps | Cloud Run | App Runner |
| Serverless (function) | Azure Functions | Cloud Functions | Lambda |
The compute layer is your only provider-lockable choice per service. Everything upstream — IaC, container images, code — stays the same.
The tradeoffs table¶
| Axis | Kubernetes (AKS / GKE / EKS) | Serverless (Container Apps / Cloud Run / App Runner + Functions / Lambda) |
|---|---|---|
| Cost floor | Non-zero — you pay for the node pool 24/7 | Scale-to-zero. No traffic → no bill. |
| Cold start | None (pods stay warm) | 100 ms – several seconds first-request latency |
| Ops burden | Cluster upgrades, node lifecycle, capacity planning | Provider owns the runtime |
| Control surface | Full k8s API — sidecars, DaemonSets, custom schedulers | The container's HTTP port + env + limits + concurrency |
| Concurrency model | You pick (HTTP server, worker pool, stateful set) | 1 request per instance (Cloud Run/App Runner) or event-per-invocation (Functions/Lambda) |
| Max request duration | Whatever your app allows | Provider-capped (Cloud Run 60 min; Lambda 15 min; Container Apps 60 min) |
| Startup time budget | Slow-start OK — pod is warm | Init has to finish inside the cold-start budget |
| State | Local disk / PVC OK for stateful sets | Stateless — persist to a managed service |
| Cross-cloud portability | Very high (Kubernetes IS the abstraction) | Low (each provider's serverless surface differs) |
Decision rules¶
Choose Kubernetes when: - You run 24×7 traffic and cold-start isn't acceptable. - You need sidecars (service mesh, log collector, GPU workload). - You'd otherwise be paying for provider infra "just in case." - You're migrating an existing containerized fleet and want portability. - Your workload holds state (persistent volumes, long-lived connections).
Choose serverless when: - Traffic is spiky, low-volume, or you want a hard $0 floor. - The unit of work is a request or event (webhook, cron, queue message). - You want zero cluster ops. - You're prototyping and don't want to pay for idle compute.
Use both when: - A steady-state backend runs on Kubernetes; a periodic batch job or webhook receiver runs on the serverless surface. - Kubernetes hosts the model server; a lightweight serverless HTTP gateway fronts it for authentication + rate limiting.
Per-provider service links¶
Official docs verified 2026-08-08
- Kubernetes: AKS — managed control plane, node pools you scale.
- Serverless container: Container Apps — Kubernetes-flavored container platform without operating the cluster.
- Function: Azure Functions — event/HTTP-triggered.
Official docs verified 2026-08-08
- Kubernetes: GKE Autopilot (managed nodes) or Standard (you manage nodes).
- Serverless container: Cloud Run.
- Function: Cloud Functions (2nd gen runs on Cloud Run under the hood).
Official docs verified 2026-08-08
- Kubernetes: EKS — control plane managed, nodes via self-managed / managed node groups / Fargate profiles.
- Serverless container: App Runner (or Fargate on ECS).
- Function: Lambda (HTTP via API Gateway or Function URLs).
Once you've chosen — next stop¶
The reusable Terraform + Helm baseline implements both compute paths per provider. Every downstream recipe (E2/E3) extends that baseline instead of reinventing the plumbing.