Most teams don't need Kubernetes. There. I said it.
I've watched three separate startups spend their first engineering quarter wiring up clusters, writing Helm charts, and debugging CrashLoopBackOff errors — all before they had a hundred paying users. The pitch is seductive: "It's what Netflix uses." Sure. Netflix also has a platform engineering team larger than your entire company. Kubernetes complexity is it worth it is a question worth asking seriously, before you've already committed.
This post is my honest take after running workloads on k8s since version 1.14, and also running plenty of things off it. I'm not here to tell you Kubernetes is bad. I'm here to tell you it has a real cost, and that cost is often invisible in the blog posts that celebrate it.
What "Complexity" Actually Means Here
When people say Kubernetes is complex, they usually mean one of three things, and conflating them is where the confusion starts.
Operational complexity. Someone has to manage the control plane, etcd backups, node upgrades, and certificate rotation. Even with managed services like EKS or GKE, you're still responsible for node pools, add-ons, and the upgrade treadmill. GKE Autopilot reduces this, but you trade control for constraints.
Conceptual complexity. Pods, ReplicaSets, Deployments, StatefulSets, DaemonSets, Services, Ingresses, NetworkPolicies, PersistentVolumeClaims — and that's before you touch RBAC or custom resource definitions. A new engineer joining your team needs weeks, not hours, to become productive. That's a real hiring and onboarding tax.
Accidental complexity. This is the one nobody talks about. Every abstraction you add on top — Helm, Kustomize, ArgoCD, Istio, cert-manager, external-dns — compounds the surface area. I've seen values.yaml files that were longer than the actual application code they deployed. That's not infrastructure as code. That's infrastructure as archaeology.
The Honest Case For Kubernetes
I don't want to strawman the other side. Kubernetes genuinely earns its keep in specific situations.
If you're running dozens of microservices with different scaling profiles, the declarative model pays off. You write a Deployment manifest once, and the reconciliation loop handles restarts, rollouts, and rollbacks without you babysitting a screen. That's real value.
Multi-tenant workloads — where you need namespace-level isolation, resource quotas, and network policies between teams — are another legitimate use case. Trying to replicate that with plain Docker or even Nomad gets messy fast.
And if you're already running on a cloud provider's managed offering (EKS, GKE, AKS), the operational floor is lower than it was in 2018. Kubernetes 1.29 on GKE Autopilot is a genuinely different experience from hand-rolling a cluster on bare metal. The gap has closed.
But "the gap has closed" is not the same as "the complexity is gone."
Where It Goes Wrong (And It Goes Wrong Often)
Here's a pattern I've seen repeatedly. A team of four engineers decides to "do Kubernetes properly." They spend two weeks standing up the cluster, another week on the ingress controller, a week on cert-manager, two days debugging why pods can't pull images from their private registry, and then — finally — they deploy their monolith as a single-replica Deployment with no horizontal pod autoscaler and a resource request that's basically a guess.
At that point, they have all the complexity of Kubernetes and almost none of the benefits. They've also burned a month of engineering time.
The specific failure mode is premature abstraction. Kubernetes is an excellent platform for managing complexity that already exists. It's a poor tool for managing complexity you haven't encountered yet.
A plain docker-compose.yml deployed on a single $20/month VPS with a systemd service and a cron job for backups will outperform a misconfigured Kubernetes cluster on every metric that matters to a small team: cost, debugging time, and time-to-deploy.
# docker-compose.yml — embarrassingly simple, embarrassingly effective
services:
app:
image: myapp:latest
restart: always
ports:
- "3000:3000"
env_file: .env
db:
image: postgres:16
restart: always
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
This config has served teams doing $1M ARR. I'm not joking.
A Rough Heuristic for When to Switch
I've landed on a few concrete signals that suggest Kubernetes complexity is actually worth it:
| Signal | Threshold |
|---|---|
| Number of independently deployable services | 8+ |
| Engineers who will own infra full-time | 1+ dedicated |
| Need for per-service autoscaling | Yes |
| Multi-tenant isolation requirements | Yes |
| Monthly cloud spend you're trying to optimize | $5,000+/mo |
If you hit three or more of these, the conversation changes. Below that, you're almost certainly paying a complexity tax with no corresponding dividend.
One more thing: the "dedicated infra engineer" row matters more than people admit. Kubernetes without someone who understands it deeply is like buying a race car and letting your teenager maintain it. The car is impressive. The outcome is not.
Managed Kubernetes vs. Rolling Your Own
If you've crossed the threshold and you're going in, please don't roll your own control plane in 2024. The era of kubeadm on bare EC2 instances should be behind you unless you have a very specific reason (air-gapped environments, cost at extreme scale, regulatory constraints).
EKS (AWS) runs around $0.10/hour per cluster (~$73/month) plus node costs. GKE Standard is similar. GKE Autopilot removes node management entirely and charges per pod resource request — interesting model, real tradeoffs on customization.
For most teams making the jump, I'd start with GKE Autopilot or EKS with managed node groups, not because they're perfect, but because they eliminate the failure modes that kill momentum in the first month. You can always go lower-level later. You can't easily get back the three weeks you spent debugging etcd quorum issues.
The Question Nobody Asks About Kubernetes Complexity
Here's what I think the real question is, and it's not "is Kubernetes complex?" (It is.) It's: who on your team will own the complexity?
Every abstraction layer has a failure mode. When Kubernetes fails — and it will, in ways that are subtle and occasionally spectacular — someone needs to understand it well enough to diagnose the problem. That means reading controller logs, understanding how the scheduler makes decisions, knowing what a Pending pod actually means versus a ContainerCreating one.
If your answer is "we'll figure it out when it breaks," that's not a strategy. That's a future incident at 2 AM with a team that's never read the Kubernetes source code trying to understand why their StatefulSet won't reschedule.
Kubernetes complexity is it worth it? For teams with scale, dedicated ownership, and genuine multi-service orchestration needs — yes, absolutely. For everyone else, the honest answer is that you're probably adopting a solution to a problem you don't have yet, and paying for it with engineering time you can't afford.
What to Do Tomorrow
Audit your actual deployment. If you're running fewer than eight services, have no dedicated infra engineer, and aren't hitting scaling walls, don't touch Kubernetes yet. Run your stack on a managed VM or a simple container service like Fly.io, Railway, or even ECS with Fargate. Revisit the decision in six months with real data.
If you're already on Kubernetes and it feels like you're fighting it more than using it, that's signal too. Simplify before you add more tooling. Kill the service mesh you added "for observability." Get back to a state where a new engineer can understand the deployment in an afternoon.
The goal is shipping software, not operating infrastructure for its own sake. Kubernetes is a means, not an end — and treating it like an end is exactly how teams end up in reproducible development environments and infrastructure complexity traps that were supposed to be solved in the first place.