"Do we need Kubernetes yet?" is almost always the wrong question. The right one is: how many services, how many hosts, and how many people are getting paged? Those three numbers tell you more than any abstract talk about "needing orchestration."
The thresholds that actually matter
We run CodeCeibe itself on a single VPS under Compose: Django, Postgres 17, Redis, an analytics worker, a scheduled-post queue worker, and nginx -- six services, one host, one person on call. Moving that to Kubernetes today would add a control plane, an etcd cluster and a YAML tree to babysit, for zero operational benefit. The table below is the set of signals we actually watch for, not a generic checklist.
| Signal | Compose is still fine | Time to look at Kubernetes |
|---|---|---|
| Services | 8 or fewer on one host | 10+ services, several teams own different ones |
| Hosts | 1 (maybe a hot standby) | 3+ hosts that need a scheduler to place work on |
| On-call team | 1-3 people who know the stack by heart | 4+ engineers rotating, nobody wants to learn "ask Alvaro" as the deploy process |
| Deploys | A few times a week, brief downtime is acceptable | 10+ times a day, zero-downtime rolling updates are a requirement, not a nice-to-have |
| Load pattern | Roughly flat, you size containers once | Traffic spikes hard enough that you need pods to scale from 2 to 12 replicas and back automatically |
What it looks like right before you've crossed it
The tell isn't a philosophical realization, it's a script. If you've started writing something like this, you've already outgrown Compose and just haven't admitted it yet:
for host in web01 web02 web03; do
ssh deploy@$host "cd /srv/app && docker compose pull && docker compose up -d --no-deps app"
sleep 15
curl -sf https://$host/healthz || { echo "rollback on $host"; break; }
doneThat's a hand-rolled, sequential, no-rollback version of what a Kubernetes Deployment gives you for free with readinessProbe and maxUnavailable: 0. Once you're writing SSH loops to fake rolling updates across hosts, the orchestrator is cheaper than the bash.
What actually changes after the switch
- Someone has to own the cluster itself -- node upgrades, CNI plugin updates, certificate rotation. That's a part-time job on a 3-node cluster and a real one past 10 nodes.
- Your deploy artifact goes from a
docker-compose.ymlanyone can read in 30 seconds to a Helm chart or a pile of manifests that needs its own review process. - You get real autoscaling, rolling updates with health-check gates, and a scheduler that bin-packs workloads across hosts -- all things Compose genuinely cannot do, because it was never designed to.
The honest answer for most small teams
If you're under 3 people and under 10 services on one host, don't migrate. Fix the actual pain point instead -- usually that's "deploys have downtime" (solved with a blue container + nginx upstream swap) or "I'm the only one who knows how to deploy" (solved with a documented runbook, not a scheduler). Kubernetes solves problems you get at scale, and it creates problems -- a second system to operate -- that you don't have yet.
