I’ve set up Kubernetes clusters for teams of three engineers. I’ve watched a solo founder spend two weeks debugging Helm charts instead of shipping features. And I’ve seen a 50-person company run their entire SaaS on a single Docker Compose file with zero regrets.
Kubernetes is an extraordinary piece of engineering. It’s also wildly overbuilt for most small teams. If you have fewer than 15 engineers and you’re not running hundreds of microservices, you’re probably paying a complexity tax that buys you nothing. The operational overhead — etcd clusters, RBAC policies, ingress controllers, service meshes, CRD management — eats hours that small teams can’t afford.
The good news: the alternatives have gotten genuinely viable. Not just toy-grade “works for side projects” tools, but real production options that trade Kubernetes’ infinite flexibility for something more valuable at small scale — simplicity.
Here are five I’d actually recommend, depending on where you sit.
1. Docker Swarm — The One You Already Know
If your team uses Docker Compose for local development (and you probably do), Swarm is the shortest path to production orchestration. It extends concepts you already understand — services, networks, volumes, compose files — into a multi-node cluster.
Setup takes minutes, not hours. You initialize a swarm on your primary node, join workers with a token, and deploy your existing compose file with docker stack deploy. Rolling updates, health checks, service discovery — it’s all built in. No Helm, no kubectl, no YAML rabbit holes.
The catch. Swarm is in maintenance mode. Docker still ships it with every Engine release, and Mirantis has committed to support through at least 2030, so it’s not going anywhere soon. But new feature development has essentially stopped. What you see today is what you’ll get. The Docker 29+ upgrade also caused real issues for some Swarm clusters, which isn’t confidence-inspiring.
Scaling has a practical ceiling, too. Swarm handles dozens of services across a handful of nodes well. Push beyond that and you’ll start feeling the lack of sophisticated scheduling, autoscaling, and observability that Kubernetes provides.
Best for: Teams running 5-20 containers who already use Docker Compose and want the fastest possible path to multi-node deployment. If your production topology looks like “a few backend services, a database, Redis, and maybe a worker queue,” Swarm handles that without breaking a sweat.
2. HashiCorp Nomad — The Quiet Workhorse
Nomad doesn’t get the attention Kubernetes does, which is a shame because it solves a lot of the same problems with dramatically less complexity. It’s a single binary — download it, run it, done. No etcd dependency, no separate API server, no controller manager. One process handles scheduling, orchestration, and cluster management.
The job specification language (HCL, the same one Terraform uses) is more readable than Kubernetes YAML, and that’s not a minor point when you’re debugging a deployment at 2 AM. A Nomad job file for a typical web service is maybe 30 lines. The equivalent Kubernetes setup — Deployment, Service, Ingress, ConfigMap — can easily run 150+.
What actually sets Nomad apart is workload flexibility. Kubernetes is laser-focused on containers. Nomad runs containers, sure, but also standalone binaries, Java applications, VMs via QEMU, and batch jobs. If you’ve got a mixed environment — a Go API server in Docker alongside a legacy Java service running directly on the host — Nomad handles both without contortion.
Nomad has been proven at scale too, with production clusters exceeding 10,000 nodes. For a small team, that headroom means you won’t outgrow it.
Where it falls short. Nomad’s ecosystem is smaller. Kubernetes has an enormous third-party tool landscape — monitoring, service meshes, GitOps controllers, policy engines. With Nomad, you’re more reliant on HashiCorp’s own stack (Consul for service discovery, Vault for secrets). If you’re not already in the HashiCorp ecosystem, that’s additional tooling to learn.
Community support is thinner too. When you hit a wall, Stack Overflow won’t have fifteen answers for your specific Nomad problem the way it would for Kubernetes. You’ll spend more time reading docs and less time copying solutions.
Best for: Teams that want real orchestration capabilities without Kubernetes’ operational weight, especially if you’re already using Terraform or other HashiCorp tools. Also a strong pick if you need to orchestrate non-container workloads alongside containers.
3. Google Cloud Run — Containers Without Clusters
Cloud Run is what happens when you strip container orchestration down to its absolute minimum surface area. You give it a Docker image, tell it how much CPU and RAM you want, and it handles everything else — scaling, load balancing, TLS, networking. There’s no cluster to manage because there is no cluster. Google runs the infrastructure; you deploy containers to it.
The pricing model is hard to argue with for small teams. You pay per request and per vCPU-second of actual compute time. For services with variable traffic — which describes most startups — this means you’re paying near-zero during quiet hours instead of keeping nodes running 24/7. The free tier is generous enough that low-traffic services can run for free indefinitely.
Cloud Run has matured considerably through 2026. Functions can now deploy directly to Cloud Run (GA), flexible committed use discounts give you 28% savings on sustained workloads, and there’s even GPU support (NVIDIA RTX PRO 6000 Blackwell) for ML inference workloads. The recently GA’d MCP server integration is interesting for teams building AI-powered applications.
The downsides. You’re locked into Google Cloud. That’s the big one. If multi-cloud portability matters to your business, Cloud Run is a non-starter.
There are also real architectural constraints. Cloud Run services are stateless and ephemeral — they can scale to zero, which is great for cost but means cold starts are a factor. WebSocket support exists but has limitations. Background processing is possible but not as natural as in a traditional server setup. And while Cloud Run handles HTTP services well, it’s not designed for long-running workers, cron-heavy architectures, or anything that needs persistent connections.
Debugging is harder too. When something goes wrong on Cloud Run, you’re debugging through Google’s logging infrastructure, not SSH-ing into a box and reading logs directly. For some teams that’s fine; for others it’s maddening.
Best for: Teams building HTTP-centric services (APIs, web apps) with variable traffic patterns who are already on Google Cloud. Particularly strong for startups where cost efficiency during low-traffic periods is critical.
4. Kamal 2 — Deploy Anywhere with Just SSH
Kamal is the most refreshingly simple tool on this list. Born out of Basecamp’s deployment philosophy, it deploys Docker containers to any server you can SSH into. No cluster manager, no control plane, no cloud provider lock-in. You point it at a server (bare metal, a $5 VPS, an EC2 instance — doesn’t matter), and it builds your Docker image, pushes it to a registry, pulls it on the server, and swaps traffic with zero downtime.
Kamal 2 (now at version 2.8.2) replaced Traefik with its own built-in proxy, which simplified the stack further. Configuration is a single YAML file that’s human-readable without a decoder ring. Multi-app deployment on a single server works out of the box. It shipped as the default deployment tool in Rails 8, but there’s nothing Rails-specific about it — any app that runs in a Docker container works.
The mental model is “Capistrano for Docker.” If you’ve ever deployed by SSH-ing into a server and pulling the latest code, Kamal is that, but automated and with zero-downtime deployments.
What you give up. Kamal doesn’t orchestrate across multiple servers the way Kubernetes or Nomad does. You can deploy to multiple servers, but there’s no built-in service discovery, no automatic failover between hosts, and no cluster-aware scheduling. Load balancing across multiple servers requires an external load balancer you set up yourself.
Scaling isn’t automatic either. Need more capacity? You provision a server and add it to your deploy config. Need less? You remove it manually. There’s no autoscaling based on CPU or request count.
This is a deployment tool, not an orchestration platform. That’s not a limitation for many small teams — it’s the entire point. But if you need containers to automatically reschedule when a node dies, or traffic to route intelligently across a fleet, Kamal isn’t trying to solve those problems.
Best for: Teams that deploy to their own servers (or cheap VPS providers like Hetzner, DigitalOcean) and want dead-simple, repeatable deployments without cloud provider lock-in. Particularly strong for teams running 1-5 services where the infrastructure is “a few boxes behind a load balancer.”
5. AWS ECS with Fargate (or the New Express Mode)
If you’re on AWS — and statistically, you probably are — ECS with Fargate is the most natural Kubernetes alternative. You define task definitions (think: pod specs but simpler), create services, and Fargate runs your containers without you managing any EC2 instances.
Here’s the thing worth knowing: AWS App Runner, which was supposed to be the “simple container deployment” service, is closing to new customers on April 30, 2026. AWS has effectively sunset it in favor of ECS Express Mode. That tells you where AWS is consolidating — and it’s ECS.
ECS Express Mode is the interesting development here. With a single API call, you provide a container image and two IAM roles, and AWS provisions a complete application stack: an ECS service on Fargate, an Application Load Balancer, auto scaling, and networking. It’s trying to deliver App Runner’s simplicity on top of ECS’s mature foundation.
Standard ECS with Fargate is more verbose to set up than Cloud Run or Kamal, but it gives you real autoscaling, tight integration with the rest of AWS (ALB, CloudWatch, Secrets Manager, IAM), and the ability to graduate to more complex setups without migrating platforms.
The fine print. ECS is AWS-only. More so than Cloud Run’s Google lock-in, ECS task definitions and service configurations are deeply AWS-specific. Migrating away means rewriting your deployment infrastructure from scratch.
The configuration surface area is larger than the other tools on this list. Even with Express Mode simplifying the initial setup, you’ll eventually need to understand task definitions, service configurations, target groups, security groups, and IAM policies. It’s simpler than Kubernetes, but it’s not simple.
Pricing can also surprise you. Fargate charges per vCPU and memory per second, and it’s not cheap compared to running your own EC2 instances. For steady-state workloads, you might find yourself paying 2-3x more than equivalent EC2 capacity. Savings Plans help, but they require commitment.
Best for: Teams already deep in the AWS ecosystem who want container orchestration with autoscaling and don’t want to manage servers. ECS Express Mode is worth evaluating if you’re starting fresh — it removes much of the initial setup pain.
How to Actually Decide
Forget feature comparison tables for a moment. Answer these three questions:
How many services are you running? If it’s under five, Kamal or Docker Swarm will serve you well with minimal overhead. The operational complexity of Cloud Run, ECS, or Nomad isn’t justified for a handful of containers.
Are you locked into a cloud provider? If you’re all-in on AWS, ECS is the path of least resistance. All-in on GCP? Cloud Run. If you want to run on bare metal, cheap VPS providers, or stay cloud-agnostic, Kamal or Nomad are your options.
Do you need autoscaling? If your traffic is spiky and unpredictable, Cloud Run and ECS with Fargate handle autoscaling natively. Nomad can do it with some configuration. Kamal and Docker Swarm require manual scaling. For many small teams with predictable traffic, manual scaling is fine — you check your dashboards, and if things are getting hot, you spin up another box.
Here’s the comparison at a glance:
| Docker Swarm | Nomad | Cloud Run | Kamal 2 | ECS/Fargate | |
|---|---|---|---|---|---|
| Setup time | Minutes | ~1 hour | Minutes | Minutes | Hours |
| Learning curve | Low | Medium | Low | Very low | Medium-High |
| Cloud lock-in | None | None | None | AWS | |
| Autoscaling | Basic | Yes | Native | Manual | Native |
| Max practical scale | ~50 services | 10,000+ nodes | Effectively unlimited | ~10 servers | Effectively unlimited |
| Cost at low traffic | Server cost | Server cost | Near-zero | Server cost | Pay-per-use |
| Stateful workloads | Supported | Supported | No | With volumes | Limited |
When You Actually Need Kubernetes
I don’t want to oversell the “Kubernetes bad” narrative. There are legitimate reasons to reach for it:
You have a dedicated platform or DevOps team. Kubernetes makes less sense when the same three engineers shipping features are also debugging ingress configurations. With a dedicated team, the operational overhead gets amortized across many product teams.
You’re running 50+ microservices. At that scale, Kubernetes’ scheduling, service discovery, and network policies start earning their keep. Trying to manage that many services with Swarm or Kamal would be its own nightmare.
You need multi-cloud or hybrid deployments. Kubernetes is the one tool that runs identically across AWS, GCP, Azure, and on-prem. If portability across cloud providers is a real business requirement (not a hypothetical one), K8s is the answer.
You’re in a regulated industry requiring specific compliance tooling. The Kubernetes ecosystem has mature solutions for network policies, pod security standards, audit logging, and policy enforcement that smaller tools lack.
For everyone else — and “everyone else” includes the vast majority of startups and small engineering teams — pick the simplest tool that solves your actual problems today. You can always migrate to Kubernetes later if you outgrow your choice. Migrating away from Kubernetes complexity you adopted prematurely is much harder.