I run client workloads on everything from a single Docker Compose VM to managed Kubernetes clusters. The pattern I keep seeing: teams adopt Kubernetes years before they need it, and pay a complexity tax every week after. Here is the decision framework I actually use.
What Compose on a VM gives you
A docker-compose.yml on a solid VM (or two, behind a load balancer) handles a surprising amount: web, workers, Redis, even the database for smaller apps. Deploys are a pull-and-restart script; logs are docker logs; the whole mental model fits in one developer's head. For most products under serious scale, this is genuinely enough.
The real signals you need Kubernetes
- You run many services that scale independently and deploy many times a day
- You need automated self-healing and horizontal autoscaling as a baseline, not an aspiration
- Multiple teams ship to shared infrastructure and need isolation, quotas, and RBAC
- Traffic is genuinely spiky and pre-provisioning VMs wastes real money
The costs nobody puts on the slide
Kubernetes is a platform you operate, even 'managed': ingress controllers, cert-manager, observability stack, upgrade cycles, YAML sprawl, and on-call knowledge that must live in more than one head. If that list made you tired, believe the feeling — it is information.
The middle ground
ECS Fargate, Cloud Run, and platforms like Fly.io give you containers, autoscaling, and zero-downtime deploys without cluster ownership. My honest recommendation for most teams: Compose until it hurts, then a managed container platform — and Kubernetes only when the signals above are undeniable.

