You have an app to ship, maybe a few. You're on AWS because that's where the credits are and where the auditors want your data. Somebody on the team said "Kubernetes" out loud, and now you're trying to decide between EKS and k3s before the week is out.
Our take, by team size:
| Team | Pick |
|---|---|
| Indie builder or a 1 to 2 person team trying the product out | k3s on a single EC2 box |
| Small team (up to 20 engineers) without a dedicated platform owner | k3s, until you have a reason to graduate |
| 20+ engineers with production traffic, multi-AZ requirements, or real compliance pressure | EKS |
At the small end, don't even open the EKS console. The $73/month control plane fee alone is larger than your entire compute bill, and you don't need any of the things EKS is good at yet.
A small team should start on k3s and ship product; you'll know when to graduate. At 20+ engineers, pick EKS as a commitment rather than a hedge. At that size the managed control plane, IRSA, and AWS-native autoscaling pay for themselves.
EKS is usually where you end up rather than where you start, and the reason has very little to do with Kubernetes itself.
The thing people get wrong
Both are Kubernetes. Same API, same manifests, same kubectl apply. If someone hands you a chart that works on EKS, it will almost certainly work on k3s without modification, and the reverse holds too. So the choice is about operations more than technology.
What you're really picking is who owns the control plane and how much of AWS you need to glue in.
EKS has AWS run the control plane. You pay $73/month per cluster for it, and you glue in IRSA, VPC CNI, the AWS Load Balancer Controller, EBS CSI, and whichever flavor of autoscaler you prefer. Upgrades happen on AWS's calendar.
With k3s, you run the control plane on an EC2 instance. It starts in under a minute, ships with Traefik and a working storage class, and upgrades when you decide. Nothing is AWS-specific unless you want it to be.
The rest of this post is the operational fallout of that choice.
Side-by-side, the useful version
| EKS | k3s on EC2 | |
|---|---|---|
| Control plane cost | $73/month/cluster | $0 |
| Minimum viable footprint | 1 control plane + 2 nodes in 2 AZs | 1 EC2 instance |
| Time to a working cluster | 15 to 25 min with eksctl, longer first time |
Under 60 seconds |
| Networking | VPC CNI (real VPC IPs, counts against subnet) | Flannel VXLAN (overlay, doesn't touch VPC IPs) |
| Ingress | ALB Controller + one ALB per group | Traefik built in |
| Storage | EBS / EFS / FSx CSI, IAM required |
local-path out of the box; add EBS CSI if you want |
| Pod IAM | IRSA (clean, audited) | Instance profile, or you bring a solution |
| Upgrades | AWS-driven, rolling managed node groups | You pick the hour; risk is yours |
| Biggest sharp edge | VPC CNI IP exhaustion, IRSA permission dance | Embedded etcd quorum loss, single-node backups |
| Honest team size | 15+ engineers, platform owner forming | 2 to 20 engineers, nobody owns infra full-time |
For a startup, anything not on this table is a rounding error.
A note on ECS
ECS often shows up as "Kubernetes but simpler." The simplicity is real, and the price is lock-in. Task definitions, services, and the deployment model are AWS-proprietary, with no portable API, no Helm, and no ecosystem that transfers.
The day you want to run the same workloads elsewhere, you rewrite every manifest. EKS and k3s both give you the same portable Kubernetes API, while ECS is a one-way door.
What the bill really looks like
Take a workload we see often: one web service, two workers, Postgres on RDS, Redis on ElastiCache, a staging environment, and room for a few PR preview environments. Call it ~8 vCPU / 16GB of production pods plus ~4 vCPU / 8GB for staging and previews.
All prices below are approximate on-demand rates in us-east-1 as of April 2026. Your numbers will vary with region, reserved capacity, and traffic profile.
k3s on EC2
| Item | Monthly |
|---|---|
3 × t3.xlarge on-demand (4 vCPU / 16GB each) |
$299 |
| 300GB EBS gp3 | $24 |
| 1 NAT gateway | $32 + traffic |
| 1 ALB in front of Traefik | $22 |
| Data transfer (moderate) | $20 |
| Total | ~$400/month |
That buys plenty of headroom. You can fit 5 to 10 services, full staging, and rotating previews on it without thinking about capacity.
EKS
| Item | Monthly |
|---|---|
| Control plane | $73 |
2 × t3.large prod nodes (for the 2-AZ story) |
$121 |
1 × t3.medium staging node |
$30 |
1 × t3.large for previews |
$60 |
| 300GB EBS gp3 | $24 |
| 1 NAT gateway | $32 + traffic |
| 2 to 3 ALBs (ALB controller per IngressGroup, typical) | $44 to $66 |
| Data transfer (higher, because VPC CNI loves inter-AZ chatter) | $25 |
| Total | ~$410 to $440/month |
The two bills look close until you add the labor, which nobody puts on the slide:
- First EKS setup takes 1 to 3 engineer-days.
- Every EKS upgrade costs a half-day of drain and verify, quarterly.
- The first VPC CNI IP exhaustion costs half a day of figuring out that
t3.largenodes only get 35 IPs. - ALB controller version pinning across upgrades is a ticket, every time.
That's real salary spent on AWS glue instead of product. On k3s, the comparable surface area is "keep an AMI up to date" and "snapshot etcd nightly."
Getting from zero to shipping
EKS: plan on a week if nobody has done this before
- VPC with public/private subnets across 2 to 3 AZs, plus NAT and route tables.
- IAM roles for the cluster, node group, and IRSA.
-
eksctl create cluster, then wait 15 to 25 minutes. - Install the AWS Load Balancer Controller, EBS CSI driver, and Karpenter (each its own IAM dance).
- Tune CoreDNS, metrics-server, and VPC CNI (prefix delegation, warm pool settings).
- Wire up Ingress with ACM and Route53.
The piece that bites first-timers is always IRSA and the OIDC provider. One typo in a trust policy and pods silently fail to assume roles.
k3s: under a day
- Launch an EC2 instance.
-
curl -sfL https://get.k3s.io | sh -. - Point DNS at it.
- Deploy.
That list is the whole setup. Traefik is running, there's a default StorageClass, and kubeconfig is at /etc/rancher/k3s/k3s.yaml, so you can be serving traffic in a lunch break. For production, add an ASG of three k3s servers with embedded etcd for HA, an NLB out front, and a nightly etcd snapshot.
The failures you'll actually hit
These are the incidents that eat your weekend.
On EKS
- Pods stuck Pending with
no IP addresses available. VPC CNI assigns real VPC IPs to every pod, and at3.largegets 35 at most. You hit it during an autoscaling event rather than during testing. The fix is prefix delegation, which requires a node recycle. - IRSA silently not working. The pod annotation, service account annotation, trust policy, OIDC provider and role policy all have to line up. One of them off and you get
AccessDeniedwith no obvious source. - ALB controller version skew after an EKS upgrade. The ALB controller has its own compatibility matrix, and if you forget to bump it, ingress stops reconciling.
- Node group upgrades that drain in the wrong order. Without PDBs, pods get evicted faster than they start elsewhere, and you take a 30-second outage during a "safe" upgrade.
On k3s
- Embedded etcd quorum loss. You were running HA on three
t3.mediumservers and the ASG replaced two of them inside five minutes, so the cluster is read-only. Recovery isk3s server --cluster-resetfrom a known-good snapshot, and you want that snapshot script working before you need it. - Local-path PVs disappearing with the node. The default StorageClass is per-node local disk, which is great for caches and terrible for your single-replica Postgres. Switch stateful workloads to RDS or add EBS CSI.
- A k3s upgrade breaking Traefik. k3s bundles Traefik, and major k3s upgrades can bump Traefik's CRDs. Pin the Traefik Helm values, or disable the bundled version and run your own.
- A single-node cluster dying with the instance. If you started all-in-one to move fast and never moved to HA, a spot interruption or AZ blip is a full outage. Migrate before production depends on it.
Both sets are learnable. The EKS failures mostly come from fighting AWS primitives, and the k3s failures from owning the operational basics yourself.
When k3s is enough
Start here if most of these are true:
- You have under 20 engineers and nobody's job title is "platform."
- You run stateless web services and workers, with state in a managed Postgres (either in-cluster on EC2 with an operator, or RDS if you prefer AWS-native), plus ElastiCache and S3 as needed.
- Single-region is fine for now.
- Compliance doesn't demand AWS-managed control plane components.
- You'd rather spend the next two sprints on product than on Kubernetes.
k3s is CNCF-certified Kubernetes. It powers Rancher's own product, and some companies run it on bare metal fleets larger than most SaaS startups will ever see. Choosing it means picking the distribution that is kindest to small teams.
When EKS earns its keep
Move to EKS (or start there, if you're already past the line) when any of these are real:
- Audit pressure: if SOC 2 or HIPAA readiness hinges on "AWS patches the control plane," use EKS.
- Fine-grained pod IAM: per-pod credentials for S3, SQS and Bedrock are much cleaner with IRSA than with instance profiles or sidecars.
- Around 50+ services or 300+ pods: k3s handles it, but upgrades and capacity get real, and Karpenter on EKS is better at that scale.
- Multi-AZ or multi-region HA as a hard requirement: k3s HA is possible, and on EKS it is the default.
- A dedicated platform hire or team: once someone owns infra full-time, they'll want managed node groups and IRSA.
- GPU pools, Graviton spot fleets, Bottlerocket or Windows nodes: EKS wires these in natively.
If none of these describe your next 12 months, you're paying EKS tax for a future you might not have.
The migration nobody sells you
When you outgrow k3s and move to EKS, your Deployments, Services, ConfigMaps, Secrets, Jobs, CronJobs and Helm charts stay unchanged. The diff is at the edges:
- Ingress: Traefik annotations become ALB controller annotations (10 to 30 lines of YAML per service).
- Storage:
local-pathPVCs move togp3; stateful workloads you already had on RDS need no change. - IAM: instance-profile or sidecar-based access becomes IRSA. A real piece of work, but mechanical.
- Autoscaling: single-ASG k3s becomes Cluster Autoscaler or Karpenter.
Plan a week or two of cleanup. k3s to EKS is also a much shorter migration than going from no Kubernetes to EKS would have been if you'd held off for 18 months.
For a deeper walkthrough of the k3s-on-AWS setup most startups land on, see How to deploy on AWS without hiring a DevOps engineer.
The real recommendation
If you're choosing today on AWS with under 20 engineers, start on k3s and ship product. Re-evaluate when a specific item on the EKS list above becomes true. You'll save money, keep your team's attention on the business, and keep a well-worn migration path open for later.
Ownkube handles the part neither EKS nor k3s gives you out of the box: the Heroku-style developer flow. You get git push to deploy, a ready-to-share URL with automatic HTTPS, one-click Postgres and a Valkey cache in your VPC, and logs, metrics, and rollbacks built into the dashboard.
Start on Starter (free forever on one AWS instance) in your own AWS account, scale to Production when your business asks for it, and keep the same workflow the whole way through.
See Ownkube pricing for Starter, Production, and Ownkube Compute, our hosted option from $5 a month. If you'd rather skip the setup, deploy your first app and we'll have you live in the time it took to read this.
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.