Why I Think Kubernetes Is Overkill for 90 Percent of Use Cases

I’m going to say something that will annoy a lot of DevOps engineers sipping their third espresso at 3 a.m. while staring at a tangled mess of YAML files. Kubernetes is a waste of time for most of you. Not because it’s bad software—it’s brilliant engineering, a distributed system marvel that Google’s Borg lineage perfected. The problem is that we’ve collectively decided it’s the default answer for running applications, when most applications don’t need a fraction of what it offers. Felix Okonkwo here, on hotpenguin.net, and I’m calling it: K8s is a sledgehammer for a thumbtack, and the industry has lost its damn mind chasing complexity.

Overhead view of a cluttered server rack with tangled cables, representing unnecessary infrastructure complexity

The Siren Song of Scale You Don’t Have

Kubernetes was born at Google to manage hundreds of thousands of containers across global data centers. It solves problems like automated bin packing, service discovery, self-healing, and horizontal scaling at a level that makes sense when you’re serving billions of requests a day. But walk into any startup or mid-sized company, and you’ll find a team of five developers running a handful of microservices with Kubernetes, proudly announcing they’ve “tamed the beast.” They haven’t. They’ve just added a layer of operational overhead that will bite them during the next outage. The math is simple: if your workload fits on three EC2 instances with a load balancer, you don’t need a control plane that consumes CPU, memory, and human sanity to manage itself.

I’ve seen teams spend weeks fine-tuning pod resource limits, debugging CNI plugin issues, and wrestling with Helm chart versioning—all for an app that gets 10,000 requests a day. That’s not engineering maturity; it’s resume-driven development. The blunt truth is that Kubernetes abstracts away infrastructure problems most teams never had, while introducing new ones they aren’t equipped to handle. Network policies, persistent storage provisioning, etcd cluster maintenance—these are full-time jobs disguised as features. Unless you’re running at a scale where manual provisioning is literally impossible, you’re paying a complexity tax for no real return.

The Operational Tax You’re Ignoring

Let’s talk about what actually happens when you adopt Kubernetes in a small team. First, you need someone who understands the internals—not just how to write a Deployment YAML, but how the scheduler scores nodes, how kube-proxy manipulates iptables rules, and how to recover a corrupted etcd database. That person commands a salary north of $150,000, and they’ll spend half their time on Kubernetes chores instead of building your product. Then you need a monitoring stack that can parse the firehose of metrics from the control plane, nodes, and pods—Prometheus, Grafana, maybe Thanos for long-term storage. Add logging with Fluentd or Loki, because debugging a container that restarts every 30 seconds without centralized logs is masochistic. Now you’re managing infrastructure to manage your infrastructure.

Compare this to running your app on a managed platform. AWS ECS Fargate, Google Cloud Run, even a plain old VPS with systemd units and a reverse proxy. These options give you container isolation and zero-downtime deployments without the cognitive load. I’ve deployed Django monoliths on a $20 DigitalOcean droplet that handled 500 concurrent users without breaking a sweat, backed by a managed Postgres instance. The setup took an afternoon, and I didn’t touch it for months. With Kubernetes, that same app would require a cluster, an ingress controller, external-dns, cert-manager, and a week of tweaking resource requests to avoid OOM kills. The operational tax isn’t just money—it’s the mental fatigue that kills team velocity.

A stressed engineer staring at multiple monitors displaying deployment dashboards and error logs

When Microservices Become a Religion

The Kubernetes hype is inseparable from the microservices cargo cult. The argument goes: monolithic apps are bad, so we must break everything into tiny, independently deployable services. And if we have microservices, we need an orchestrator to manage them. This is backwards logic. Microservices solve organizational scaling problems—allowing multiple teams to work on different system parts without stepping on each other. They introduce network latency, distributed transaction nightmares, and debugging complexity that most product teams can’t afford. I’ve consulted for e-commerce companies that split their checkout flow into seven services, only to discover that a simple order required 14 network calls across unreliable services, with a P99 latency of three seconds. They remerged into a modular monolith and cut infrastructure costs by 60%.

The industry needs to relearn that separation of concerns doesn’t require network boundaries. Well-structured monoliths with clear module interfaces, background job processors, and read replicas can scale surprisingly far. Stack Overflow ran on a monolith for years with minimal hardware. Basecamp still does. If you’re not dealing with independent team boundaries, you’re not building microservices—you’re building a distributed ball of mud, and Kubernetes will happily host that mud until it collapses under its own weight. Stop letting architecture astronauts dictate your stack.

The Hidden Cost of Cluster Maintenance

Let’s get specific about what maintaining a Kubernetes cluster actually entails. Upgrades are a prime example. The Kubernetes project releases a new minor version every four months, with a support window of roughly a year. If you’re on a managed service like EKS or GKE, the control plane upgrade is handled, but node groups, add-ons, and API version deprecations are your problem. I’ve watched teams delay upgrades for 18 months because they were afraid of breaking their custom admission webhooks or CSI drivers. When they finally pulled the trigger, they spent two weeks testing in staging, only to hit a production issue with a deprecated Ingress API that routed traffic to the wrong service. The downtime cost more than their monthly infrastructure bill.

Then there’s the security patch treadmill. Every component in the ecosystem—CoreDNS, kube-state-metrics, the ingress controller—has its own CVE stream. Keeping up requires a CI pipeline that rebuilds images, scans for vulnerabilities, and rolls out updates without breaking compatibility. This is not optional. An unpatched kubelet exposes your entire cluster to container escape exploits. Most small teams I know handle this by ignoring it until a penetration test screams at them, which is a disaster waiting to happen. Simpler platforms abstract this away because their attack surface is smaller and the vendor handles patching. You’re not getting credit for doing it yourself; you’re just accumulating risk.

A developer looking at a whiteboard filled with complex deployment architecture diagrams and arrow connections

The Right Tool for the Right Job

I’m not saying Kubernetes has no place. If you’re running a multi-tenant SaaS platform with hundreds of services, dynamic scaling requirements, and a dedicated platform engineering team, then Kubernetes earns its keep. The declarative API, the extensibility through CRDs, and the ecosystem of operators can turn infrastructure management into a software problem that’s actually solvable at scale. But that’s maybe 10% of the companies I encounter. The other 90% are cargo-culting because they saw a conference talk or because their CTO wants “cloud-native” on their LinkedIn profile.

The alternative stack depends on your actual needs. For a standard web application, consider:

  • A managed container service like Cloud Run or ECS Fargate for stateless workloads.
  • A PaaS like Render or Fly.io that handles deployments from a Git push.
  • A VPS with Ansible or even a simple bash script for provisioning, combined with a systemd service file for process supervision.
  • A managed database service so you’re not babysitting Postgres or MySQL yourself.

These options handle the 80% case: reliable deployments, health checks, and log aggregation, without the 80% overhead. I’ve migrated three companies off self-managed Kubernetes onto Cloud Run, and in each case, their deployment frequency increased because developers weren’t afraid of breaking the cluster. The ops burden shifted from writing Helm charts to writing application code, where it belongs.

Developer Experience Matters More Than YAML Purity

One of the most frustrating arguments I hear is that Kubernetes provides a “unified” platform for everything. In theory, yes—you can run batch jobs, web services, and databases all on the same cluster. In practice, running stateful workloads on Kubernetes is a special circle of hell. PersistentVolumeClaims and StatefulSets sound elegant until a node fails and your volume gets stuck in Terminating state, or your cloud provider’s CSI driver decides to detach a disk from a running pod. I’ve lost data this way. Not because Kubernetes is fundamentally broken, but because the edge cases in storage orchestration are numerous and poorly understood by teams who just wanted a database.

Developer experience should be the primary metric for infrastructure choices. Can a new hire deploy a feature branch to a staging environment in their first week without reading a 50-page runbook? Can you roll back a bad release with a single command, or does it require kubectl surgery? The tools that make these workflows simple are the ones that scale your team, not the ones that scale your container count. Kubernetes optimizes for the latter, often at the expense of the former. If your local development setup requires minikube, Skaffold, and a prayer, you’ve already lost.

FAQ

When is Kubernetes actually the right choice?

Kubernetes makes sense when you have a large engineering organization with multiple teams needing independent deployment cadences, or when you’re operating at a scale where manual infrastructure management becomes impossible. If you’re running hundreds of services, need sophisticated traffic routing (canary deployments, A/B testing), and have a dedicated platform team to abstract Kubernetes from developers, it’s a solid foundation. The key indicator is when the complexity of your system exceeds the complexity of managing Kubernetes itself.

What’s a simpler alternative for small teams running microservices?

For small teams, a managed container platform like AWS ECS Fargate or Google Cloud Run provides container orchestration without the control plane overhead. You define your containers, set CPU and memory, and the platform handles placement, scaling, and load balancing. If you don’t need containers, a Platform as a Service (PaaS) like Heroku or Render automates deployments from Git and manages the runtime. These options trade some flexibility for dramatically lower operational burden, which is usually the right trade-off for teams under 20 engineers.

Can’t managed Kubernetes services solve the complexity problem?

Managed Kubernetes services like EKS, GKE, and AKS reduce some operational toil—they handle the control plane, etcd backups, and often provide integrated networking and logging. But they don’t abstract away the Kubernetes API or the need to understand its objects. You’re still writing Deployments, Services, and Ingresses, still debugging pod scheduling failures, and still managing cluster add-ons. Managed services shave off maybe 30% of the complexity, but the remaining 70% is inherent to the Kubernetes model. For many teams, that’s still too much.

How do I convince my team to move away from Kubernetes?

Start with a cost-benefit analysis that includes engineering time, not just infrastructure bills. Track how many hours per sprint are spent on Kubernetes-related incidents, upgrades, or debugging. Compare that to business outcomes. Then propose a pilot project: migrate a non-critical service to a simpler platform and measure deployment speed, reliability, and team satisfaction. Data beats dogma. If the numbers show that Kubernetes is slowing you down, the conversation shifts from “best practice” to “what’s best for our product.”

I’ll leave you with this: infrastructure should be boring. It should run quietly in the background while you focus on features that matter to users. If you’re spending more time discussing CNI plugins than customer problems, you’ve built a job-creation scheme, not a product. Kubernetes is an incredible tool, but it’s a tool for a specific job. The majority of you are using it because it’s trendy, not because it’s necessary. Admit that, and you’ll free up an enormous amount of energy for work that actually moves the needle.