How to Cut Your EKS Bill: An AWS-Specific Playbook
Nobody's EKS bill is high because of the $72-a-month control plane. It is high because of everything around it: nodes sized for inflated requests, on-demand pricing where Spot would do, a NAT gateway quietly metering gigabytes, and EBS volumes nobody remembers attaching. This guide is the AWS-specific version of our Kubernetes cost optimization playbook — the levers in the order we pull them on real EKS estates, with the traps that are unique to Amazon's platform.
First, know where the money actually goes
Open Cost Explorer and group by service. A typical EKS estate splits roughly like this: EC2 (the nodes) takes the lion's share, then EBS volumes and snapshots, load balancers, NAT gateway and inter-AZ data transfer, CloudWatch, and finally the EKS control-plane fee — almost always the smallest line. That ordering is the guide's table of contents: optimize nodes first, storage and network second, and do not spend an afternoon on the control-plane fee at all. One exception worth checking immediately: clusters running a Kubernetes version past end-of-support are billed extended support at several times the standard control-plane rate. Upgrading a forgotten cluster off extended support is free money.
1. Right-size requests — the universal first step
EKS is still Kubernetes: the scheduler reserves capacity by requests, the Cluster Autoscaler or Karpenter adds nodes when requests fill up, and EC2 bills for those nodes whether the capacity is used or not. If your pods request 2–5× what they use — and in our audits they usually do — everything else in this guide is optimizing an inflated baseline. Run the Vertical Pod Autoscaler in recommendation-only mode, compare a week of Prometheus usage history against requests, and shrink the gap service by service. The main playbook covers the mechanics; do it before buying any commitments, or you will be pre-paying for the waste.
2. Karpenter with consolidation — the biggest EKS-specific win
If you do one AWS-specific thing from this guide, replace static node groups with Karpenter. The classic Cluster Autoscaler can only add and remove nodes inside fixed-size node groups you defined up front; Karpenter provisions exactly the instances your pending pods need, from the full EC2 catalog, in seconds. Two behaviors drive the savings:
- Instance selection. Karpenter picks the cheapest instance types (and Spot pools) that satisfy each batch of pending pods, instead of stamping out one node shape for everything.
- Consolidation. With
consolidationPolicy: WhenEmptyOrUnderutilized, Karpenter continuously looks for nodes whose pods would fit elsewhere — or on a cheaper replacement node — and drains them. This is the mechanism that converts your right-sizing work into actual node reductions; without it, freed capacity just idles.
Set PodDisruptionBudgets first so consolidation churn is safe, and use consolidateAfter to keep it from thrashing during deploys. The full comparison — including when the old autoscaler is still the right call — is in Karpenter vs Cluster Autoscaler.
3. Spot instances for everything that can tolerate them
Spot runs 60–90% below on-demand and Karpenter makes it operationally easy: add karpenter.sh/capacity-type: ["spot", "on-demand"] to a NodePool and it will prefer Spot, fall back to on-demand, diversify across pools, and handle the two-minute interruption notice gracefully. Start with CI runners, queue consumers and batch jobs; expand to stateless web tiers once PDBs and readiness probes have proven themselves. Keep singletons, databases and anything with slow startup on on-demand.
4. Graviton: the same bill, 20–40% smaller
AWS's ARM-based Graviton instances consistently deliver better price-performance than comparable x86 — typically in the 20–40% band for the workloads we run. Most modern runtimes (JVM, Go, Node, Python) and mainstream images ship multi-arch, so migration is usually: build with --platform linux/arm64 (or a multi-arch manifest), test, then let Karpenter mix Graviton into the fleet by adding arm64 to the NodePool's architecture requirements. Pin the stragglers that have x86-only dependencies to amd64 with a nodeSelector and migrate the rest.
5. Savings Plans — after the cleanup, never before
A Compute Savings Plan gives up to ~66% off in exchange for a 1–3 year hourly-spend commitment, and it applies across instance families, regions, and even Fargate — which makes it the right commitment vehicle for a Karpenter-managed fleet whose instance mix changes hourly. The discipline that matters: commit last. Right-size, enable consolidation, move the movable to Spot, let the fleet settle for a month, then read your new on-demand floor off Cost Explorer and cover roughly that baseline. Spot usage is already discounted and should not be covered by commitments.
6. The data-transfer traps: NAT gateways and cross-AZ traffic
Two line items surprise almost every EKS team:
- NAT gateway data processing. Private-subnet nodes reach the internet through a NAT gateway that charges per hour and per gigabyte processed. Image pulls are a classic offender: every node pulling from ECR or Docker Hub through NAT pays per gigabyte. Add VPC endpoints for ECR and S3 (which ECR uses for image layers) so pulls bypass NAT entirely — for most clusters the endpoint cost is far below the NAT processing it eliminates. Check what else transits NAT before assuming; a high-egress workload may justify a NAT instance or per-AZ gateways.
- Cross-AZ traffic. AWS charges in both directions for data crossing availability zones, and a three-AZ microservice mesh pays it on every chatty hop. Enable topology-aware routing so services prefer same-zone endpoints, and check that your load balancers are not cross-zone-balancing high-volume internal traffic unnecessarily.
7. EBS: gp3, orphans, and snapshot sprawl
- Migrate gp2 to gp3. gp3 is about 20% cheaper per GB with better baseline performance, and volumes can be modified in place. Make gp3 the default in your StorageClass and convert the existing fleet.
- Delete unattached volumes. Deleting a StatefulSet or Deployment does not delete its PVCs; each Released or unbound volume bills monthly forever. Sweep for them, and set the StorageClass
reclaimPolicydeliberately. - Lifecycle your snapshots. Snapshot stores grow monotonically unless a policy (e.g. Data Lifecycle Manager) prunes them.
8. CloudWatch: the observability bill hiding inside the platform bill
Container Insights, log ingestion and high-resolution custom metrics are billed per GB and per metric, and a verbose cluster can spend hundreds of dollars a month telling CloudWatch things nobody reads. Set log retention explicitly (the default is never expire), drop debug-level logs at the agent, and consider shipping to a cheaper store if you are ingesting heavily. The same logic applies to Prometheus cardinality if you run AMP.
The order of operations, summarized
- Check for extended-support clusters and upgrade them off the surcharge.
- Right-size requests from measured usage (VPA in recommendation mode).
- Adopt Karpenter with consolidation enabled; set PDBs first.
- Move fault-tolerant workloads to Spot via NodePool capacity-type.
- Mix Graviton into the fleet with multi-arch images.
- Add VPC endpoints for ECR/S3; enable topology-aware routing.
- Default StorageClass to gp3; sweep orphaned volumes and snapshots.
- Cap CloudWatch retention and ingestion.
- Let it settle a month, then cover the new baseline with a Savings Plan.
What would this save on your bill?
Feed your monthly AWS spend into the free calculator for a sixty-second estimate of the waste — or get the free audit and we will run this exact playbook against your account and hand you the findings.
Frequently asked questions
Why is my EKS bill so high?
Almost never because of EKS itself — the control plane is about $72/month per cluster. The bill is high because of what surrounds it: EC2 nodes sized for requests that are 2–5× above real usage, on-demand pricing where Spot would do, NAT gateway data processing charges, cross-AZ traffic between chatty services, unattached EBS volumes and CloudWatch log ingestion. Right-sizing plus Karpenter consolidation typically cuts the compute portion 30% or more.
Does Karpenter reduce EKS costs?
Yes, and it is usually the single highest-leverage change on EKS. Karpenter picks the cheapest instance types that fit your pending pods (including Spot), bin-packs aggressively, and its consolidation feature actively replaces underutilized nodes with fewer, cheaper ones. Teams moving from static node groups to Karpenter with consolidation routinely report 20–40% lower compute cost. Karpenter itself is open source and free.
Is Spot safe for production on EKS?
For stateless, replicated workloads, yes — with guardrails. Diversify across many instance types and zones so one pool drying up cannot take out capacity, set PodDisruptionBudgets so drains are graceful within the two-minute interruption notice, and keep a small on-demand baseline for critical services. Singletons and stateful primaries should stay on-demand.
How much does EKS cost per month?
The EKS control plane costs about $0.10/hour, roughly $72–75/month per cluster (more on extended support for old Kubernetes versions). Everything else is regular AWS billing: EC2 or Fargate for nodes, EBS for volumes, ELB for load balancers, NAT gateway and inter-AZ data transfer, plus CloudWatch. A small production cluster typically lands between $500 and a few thousand dollars monthly — dominated by the nodes, not the control plane.
Deciding whether EKS is even the right home for your workloads? Our EKS vs AKS vs GKE comparison covers the cost and day-2 differences honestly — and for the platform-agnostic fundamentals, start with the complete cost optimization playbook or the 24-point checklist.
Related: Kubernetes cost
- Kubernetes Cost Optimization: The Complete Playbook
- Kubernetes Cost Optimization Checklist: 24 Checks That Cut Your Bill
- Karpenter vs Cluster Autoscaler: Which Saves More Money?
- EKS vs AKS vs GKE: Which Should You Choose in 2026?
- Managed Kubernetes vs In-House: The Real Cost Comparison
- Cloud Cost Waste Calculator — estimate your overspend in 60 seconds
- Free DevOps audit — get your real waste number, measured
Need this done, not just read about?
Deplyra builds, ships and runs exactly this in production — as code, with GitOps, handed over documented.
Start a project →