6 min read
On this page

When You Don't Need Kubernetes

Kubernetes is a powerful system for managing containers at scale. It is also one of the most complex pieces of infrastructure you can adopt. Before committing to it, you should honestly evaluate whether you need it. Most startups and small teams do not. Docker Compose on a single VPS handles more than most people think, and the operational overhead of Kubernetes is significant.

The Overhead

Kubernetes is not free. Even with a managed service (EKS, GKE, AKS), you pay in complexity, learning curve, and operational burden.

Learning Curve

Kubernetes has a steep learning curve. The core concepts (Pods, Deployments, Services) are learnable in a week. Operating Kubernetes in production -- networking, RBAC, resource management, debugging, upgrades -- takes months of experience.

Concepts a developer needs to understand to deploy to Kubernetes:
  Pods, Deployments, ReplicaSets, Services, Ingress, ConfigMaps,
  Secrets, Namespaces, ServiceAccounts, RBAC, PersistentVolumeClaims,
  StorageClasses, NetworkPolicies, HPA, PDB, resource requests/limits,
  liveness probes, readiness probes, init containers, sidecars,
  Helm charts (or Kustomize), kubectl, container registries,
  Dockerfiles, image tagging strategies, rollout strategies

Concepts a developer needs to deploy to a VPS:
  SSH, Docker, Docker Compose, systemd (maybe), nginx (maybe)

Operational Complexity

Someone has to keep the cluster running. Even with managed Kubernetes, you still need to:

  • Upgrade cluster versions (Kubernetes releases every four months)
  • Manage node pools and scaling
  • Configure networking (CNI plugins, Ingress controllers, DNS)
  • Set up monitoring and logging for the cluster itself
  • Handle RBAC and security policies
  • Debug networking issues (Service mesh? Network policies? DNS? CNI?)
  • Manage Helm charts or Kustomize overlays

This is a part-time job at minimum. For a small team, it can consume an engineer's entire week.

Cost

Managed Kubernetes is not cheap. The control plane alone costs 7075/monthonEKSandGKE.Workernodescostextra.Loadbalancerscostextra.Persistentvolumescostextra.Aminimalproductioncluster(3nodes,controlplane,loadbalancer)easilycosts70-75/month on EKS and GKE. Worker nodes cost extra. Load balancers cost extra. Persistent volumes cost extra. A minimal production cluster (3 nodes, control plane, load balancer) easily costs 300-500/month before you run a single application pod.

Minimal Kubernetes cluster (AWS EKS):
  Control plane:                     $73/month
  3x t3.medium worker nodes:        $90/month
  Application Load Balancer:         $25/month + traffic
  EBS volumes:                       $10-50/month
  Total:                            ~$200-240/month

Equivalent on a single VPS:
  1x 4-core, 8GB RAM VPS:          $20-50/month
  Docker Compose:                    $0
  Total:                            $20-50/month

The VPS handles the same workload for a fraction of the cost, with far less operational complexity.

What Docker Compose on a VPS Can Handle

A single modern VPS (4 cores, 8 GB RAM, NVMe storage) running Docker Compose can serve:

  • Thousands of concurrent users for a typical web application
  • A web server, API, database, cache, and background workers simultaneously
  • Hundreds of requests per second before you hit any bottleneck
# compose.yml -- a complete production stack on a single server
services:
  app:
    image: ghcr.io/myorg/app:v1.2.3
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/myapp
      REDIS_URL: redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 2G

  worker:
    image: ghcr.io/myorg/app:v1.2.3
    command: python -m celery -A tasks worker
    environment:
      DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/myapp
      REDIS_URL: redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  cache:
    image: redis:7-alpine
    restart: unless-stopped

  caddy:
    image: caddy:2-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    restart: unless-stopped

volumes:
  pgdata:
  caddy_data:

Deployment is SSH + docker compose pull && docker compose up -d. Add a simple script or a basic CI/CD pipeline and you have automated deployments. Caddy handles TLS certificates automatically.

When Kubernetes Makes Sense

Kubernetes earns its complexity in specific scenarios:

Multiple Teams, Many Services

When you have 10+ teams deploying 50+ services, you need standardized deployment, resource isolation, and access control. Kubernetes provides namespaces, RBAC, resource quotas, and a consistent deployment model across all teams.

5 engineers, 2 services:    VPS + Docker Compose
20 engineers, 10 services:  Maybe Kubernetes, maybe not
50 engineers, 30 services:  Kubernetes makes sense
200 engineers, 100 services: Kubernetes is almost certainly necessary

Auto-Scaling Requirements

If your traffic is unpredictable -- spiky e-commerce, event-driven workloads, seasonal patterns -- Kubernetes Horizontal Pod Autoscaler and cluster autoscaler can scale pods and nodes automatically. Docker Compose on a VPS requires you to provision for peak load all the time.

High Availability Requirements

If a server failure must not cause downtime, you need workloads distributed across multiple servers. Kubernetes handles this natively. Docker Compose runs on a single host -- if it goes down, everything goes down.

Compliance & Governance

Large organizations often need network policies, pod security standards, audit logging, and fine-grained access control. Kubernetes provides all of these. Docker Compose does not.

Standardized Developer Experience

When you want every team to deploy the same way -- push to Git, CI builds an image, CD deploys to Kubernetes -- the platform team can build that on Kubernetes. The consistency across teams reduces cognitive load even if each individual team would be faster on a VPS.

When Kubernetes Does Not Make Sense

Solo Founder or Small Team

If you are 1-5 engineers, every hour spent on Kubernetes infrastructure is an hour not spent on your product. The infrastructure is not your competitive advantage.

Single Service, Predictable Load

A monolithic application serving steady traffic does not benefit from pod autoscaling, service meshes, or multi-node scheduling. A VPS with a database handles this workload trivially.

Early-Stage Startups

You do not know your architecture yet. You do not know your traffic patterns. You do not know if the product will survive. Investing in Kubernetes now is optimizing for a future that may never arrive.

Startup math:
  Time to set up Kubernetes properly:  2-4 weeks
  Time to set up VPS + Compose:        1-2 days
  Probability the startup pivots in 6 months: high
  Probability the VPS can't handle the load: low

Budget-Constrained Projects

When every dollar matters, the cost difference between a managed Kubernetes cluster and a VPS is significant. That $200+/month could fund development time instead.

The Middle Ground: Managed Container Services

If Docker Compose is too simple but Kubernetes is too complex, consider managed container services:

AWS ECS + Fargate:    Define tasks and services. AWS manages the infrastructure.
                      No cluster to maintain. Pay per container.

Google Cloud Run:     Push a container image, get a URL. Auto-scales to zero.
                      Perfect for APIs and web services.

Azure Container Apps: Similar to Cloud Run. Managed Kubernetes under the hood,
                      but you never touch kubectl.

Fly.io:               Deploy containers globally. Simple CLI. Good for small
                      to medium workloads.

These services give you container orchestration (scaling, health checks, rolling updates) without the operational burden of managing a Kubernetes cluster.

A Decision Framework

Question 1: Do you have more than 10 services?
  No  -> You probably don't need Kubernetes.
  Yes -> Continue.

Question 2: Do you have more than 3 teams deploying independently?
  No  -> You probably don't need Kubernetes.
  Yes -> Continue.

Question 3: Do you need auto-scaling for unpredictable traffic?
  No  -> A managed container service (ECS, Cloud Run) might be enough.
  Yes -> Continue.

Question 4: Do you have at least one engineer who can dedicate significant
            time to cluster operations?
  No  -> Use a managed container service instead.
  Yes -> Kubernetes is a reasonable choice.

Real-World Example

A SaaS startup with 4 engineers started on Kubernetes because "we'll need it eventually." The CTO spent 30% of his time maintaining the cluster, debugging networking issues, and upgrading Helm charts. Their single API served 200 requests per minute.

They migrated to a $40/month VPS running Docker Compose. Deployments went from a 15-minute Helm rollout to a 30-second docker compose up -d. The CTO got 30% of his time back to work on the product. Two years later, with 15 engineers and 8 services, they migrated to Kubernetes -- and this time the complexity was justified.

Common Pitfalls

  • Premature Kubernetes adoption -- Adopting Kubernetes before you need it means paying the complexity tax without the benefits. Start simple. Migrate when the pain of simplicity exceeds the cost of complexity.
  • "Everyone uses it" reasoning -- Netflix uses Kubernetes. You are not Netflix. Make decisions based on your team, your scale, and your constraints.
  • Ignoring managed alternatives -- Cloud Run, ECS Fargate, and similar services handle 80% of use cases with 20% of the complexity. Evaluate them before committing to Kubernetes.
  • Underestimating operational cost -- "It's managed Kubernetes, so we don't need to manage it." Managed means the control plane is managed. You still manage everything else: node pools, networking, RBAC, monitoring, upgrades.
  • Over-provisioning for hypothetical scale -- Provisioning a 10-node cluster for an application that gets 100 requests per minute is burning money on infrastructure you do not need.
  • Sunk cost fallacy -- "We already set up Kubernetes, so we should keep using it." If it is costing more than it saves, migrate to something simpler. The time already spent is gone regardless.

Key Takeaways

  • Kubernetes solves real problems at scale: multi-team, multi-service, auto-scaling, high availability
  • For most small teams (under 10 engineers) and simple architectures (under 5 services), a VPS with Docker Compose or a managed container service is sufficient
  • The operational overhead of Kubernetes is significant: learning curve, cluster management, networking, upgrades, and cost
  • Managed container services (ECS Fargate, Cloud Run, Azure Container Apps) offer a middle ground with container orchestration but without cluster management
  • Start simple. Migrate to Kubernetes when the pain of simplicity exceeds the cost of complexity, not before.
  • Every hour spent on infrastructure is an hour not spent on your product. Choose the simplest infrastructure that meets your actual requirements.