- Most EKS bills run 30-50% higher than necessary, driven by stranded CPU and memory requests and by cost categories like cross-AZ data transfer and orphaned EBS volumes, not the $73/month control plane fee.
- Rightsizing before committing to a Savings Plan is the single highest-leverage sequencing decision teams get wrong.
- A phased rollout of audit, rightsize, automate, and govern gets teams to 40-60% savings without a reliability incident.
- Zesty continuously rightsizes pods and optimizes pod placement in real time, so savings don’t erode as workloads change week to week.
Introduction
Amazon Elastic Kubernetes Service (EKS) cost optimization efforts stall for a simple reason: teams treat cost cutting as a scattered checklist of tips instead of an ordered sequence, so gains from one tactic get undone by the next change to the cluster. A team rightsizes a handful of deployments this quarter, then locks in a Savings Plan before the new sizing settles, or turns on autoscaling without first cleaning up the orphaned volumes and idle load balancers sitting in the background. Each fix looks reasonable in isolation. Together, without sequencing, they leave 30-50% of the bill sitting on the table indefinitely.
Reduce EKS costs by working through waste in the order it actually compounds, not the order that’s easiest to fix. That’s what this framework does: audit before touching anything, rightsize before committing to any pricing discount, automate scaling once the baseline is clean, then govern so the gains hold as clusters change. Each phase depends on the one before it, which is why skipping ahead is the most common reason optimization projects stall halfway through.
For the complete, broader picture across all ten EKS cost practices, control plane, compute, storage, and networking, see our Amazon EKS Cost Optimization: 10 Best Practices.
EKS Pricing: What’s Actually in Your EKS Bill (Cost Composition)
EKS pricing looks simple on paper, a flat $0.10 per hour per cluster for the control plane, roughly $73 a month, but that line item is rarely what’s driving the total bill. Extended Support for clusters running unsupported Kubernetes versions adds another $0.60/hour per cluster, which is worth checking since it’s easy to leave running long after an upgrade would have removed the need for it. The real driver sits above the control plane: worker node costs, Elastic Block Store (EBS) storage, load balancers, and data transfer.
Worker node costs, whether EC2 or Fargate, typically account for 60-70% of total spend and are where most overprovisioned CPU and memory requests turn into hard dollars, since Kubernetes schedules pods based on requested resources, not actual usage, and idle capacity still gets billed at the instance rate.
Data transfer charges are the least visible category. Chatty pod-to-pod traffic that crosses Availability Zones (AZs) triggers per-GB fees that rarely show up until finance flags a spike, by which point weeks of unnecessary cross-AZ chatter have already been billed.
| Cost Component | Typical Share of Bill | Main Waste Driver |
|---|---|---|
| Control plane | Under 5% | Extended Support left on after an upgrade |
| Worker nodes (EC2/Fargate) | 60-70% | Overprovisioned CPU/memory requests forcing extra nodes |
| EBS storage | 10-15% | Oversized gp3 volumes, orphaned volumes, unnecessary snapshots |
| Load balancers | Under 5% | Idle or unused ALBs/NLBs left running |
| Cross-AZ data transfer | 5-10% | Chatty inter-AZ traffic between pods and nodes |
Switching orphaned or oversized volumes from gp2 to gp3 typically cuts storage costs by about 20%, though it doesn’t address the underlying overprovisioning. Compute and data transfer together typically represent 75-80% of correctable waste, which is why the first two phases of this framework focus there before storage and governance. Zesty’s platform enables real-time cost visibility into requested versus actual pod usage across clusters, making granular costs visible continuously, instead of through a quarterly export that’s already stale by the time anyone reads it.
Phase 1: Audit Before You Touch Anything
What should you audit first in EKS? Cost allocation tags, applied consistently across every namespace and workload, since nothing else in this framework works without knowing which team or service is generating which cost.
Enable Cost Allocation Tags First
Cost allocation tags turn a single AWS bill into cost split out by team, namespace, and environment. Without them, rightsizing decisions in Phase 2 default to guesswork instead of data, and governance in Phase 4 has nothing concrete to enforce against.
Work through this checklist before changing anything in the cluster:
- Enable and enforce cost allocation tags across every namespace, workload, and environment (prod/staging/dev) so every dollar traces back to an owner.
- Track daily spend trends, not just the monthly total, so a spike is caught within days instead of showing up as a surprise on the next invoice.
- Compare provisioned vs requested CPU and memory at the pod level; a large gap between what’s requested and what’s provisioned on the node is the clearest early signal of overprovisioning.
- Pull historical cost allocation by team and namespace for the last 60-90 days to establish a baseline before anything changes.
- Identify orphaned EBS volumes (unattached for 30+ days) and idle load balancers (no active targets), since these cost money with zero corresponding workload.
This audit typically takes one to two weeks for a mid-sized cluster and should produce a written baseline: current daily spend, current provisioned versus requested ratios by namespace, and a list of orphaned resources ready to reclaim. For the specific metrics that prove this baseline actually improved later, see our EKS Cost Optimization: Compute Savings Stack, Ranked by ROI. Skipping straight to rightsizing without this baseline makes it impossible to prove savings later, since there’s nothing to compare the after state against.
Zesty’s compute cost visibility covers most of this list automatically, tracking provisioned versus requested resources per pod in real time instead of through a one-time audit that’s outdated within a sprint.
Phase 2: Pod Rightsizing Before You Commit to Anything
Pod rightsizing is the core of Phase 2, and it addresses the single biggest waste pattern in most EKS clusters: pods requesting far more CPU and memory than they use, which forces the cluster to scale out nodes it doesn’t actually need.
It’s the equivalent of renting a 50-seat bus to move 3 people to work every day. The bus shows up, burns fuel, and gets billed whether 3 or 30 people are on it. Pods that request 4 CPU cores and 8GB of memory but consistently use a fraction of that force Kubernetes to schedule as if every pod needs the full request, which pushes the Cluster Autoscaler or Karpenter to add nodes that mostly sit idle.
Rightsize before you commit to a Savings Plan. Buying a 1- or 3-year Savings Plan against overprovisioned usage locks in the waste for the length of the commitment, since the discount applies to whatever capacity is already reserved, not to what the workload actually needs.
Fixing this means correcting resource requests and limits so they reflect real, observed usage rather than a conservative guess made during initial deployment. EKS rightsizing done well also means matching instance types to workload shape: compute-optimized instances for CPU-bound services, memory-optimized instances for workloads like caches or JVM-heavy services that hold large in-memory state, and burstable instances for spiky, low-baseline workloads like internal tooling or batch jobs that idle most of the day.
Steps that make up a working rightsizing process:
- Pull 2-4 weeks of actual CPU/memory utilization per pod from metrics-server or a monitoring stack.
- Set requests to the observed p90-p95 usage, with limits set higher to allow headroom for spikes.
- Re-run this process after major traffic pattern changes, since a one-time rightsizing pass decays as workloads evolve.
- Match instance families to workload shape before scaling node groups, rather than defaulting to a single general-purpose type across the fleet.
None of this is a one-time exercise. Traffic patterns, deployment frequency, and team headcount all shift, and each shift moves the correct request size, so a rightsizing pass that was accurate in Q1 can be meaningfully wrong by Q3 without a single line of code changing.
Manually pulling utilization data, resetting requests, and rechecking instance fit every few weeks is exactly the kind of repetitive tuning most platform teams don’t have time to sustain. Zesty’s Multi-Dimensional Autoscaling (MDA) rightsizes pod requests continuously against actual usage, so the bus resizes itself as ridership changes instead of waiting for the next manual review.
Phase 3: Automate Scaling and Bin-Packing
Horizontal Pod Autoscaler (HPA), Vertical Pod Autoscaler (VPA), and Karpenter Each Solve Part of the Problem
The Horizontal Pod Autoscaler (HPA) adds and removes pod replicas based on load, the Vertical Pod Autoscaler (VPA) adjusts resource requests on existing pods, and Karpenter (or the older Cluster Autoscaler) adds and removes nodes to match what’s actually scheduled. Each tool solves a real piece of the autoscaling problem, but they can conflict when configured independently: VPA adjusting a pod’s requests mid-cycle while HPA is still scaling out based on stale metrics can trigger a scheduling loop where the cluster adds nodes it didn’t need, right as VPA’s smaller requests would have made that unnecessary. The Kubernetes descheduler adds a related but distinct consolidation mechanism worth understanding separately, see our Practical Framework for Cutting Kubernetes Compute Costs.
Bin-packing, consolidating workloads onto fewer, more densely utilized nodes, closes the gap Karpenter alone doesn’t always catch. A cluster can have correctly sized pods and still run 30% more nodes than necessary if those pods are scattered thinly across many partially empty nodes instead of packed tightly onto fewer of them. Karpenter cost savings come from matching node capacity to actual scheduled pods rather than static node groups, but those savings only materialize fully when paired with bin-packing and correctly sized pod requests upstream. Tighter packing has its own trade-off worth knowing before enabling it, see the bin-packing-vs-latency section in our 5-Layer Stack.
Spot instances add another lever: workloads that can tolerate interruption run at a steep discount versus on-demand pricing, provided there’s automatic fallback to on-demand capacity when spot inventory runs short, so a spot reclaim doesn’t turn into a production incident.
The problem with tuning all of this manually is that it drifts. An autoscaler configuration calibrated correctly against Q1’s traffic shape, deployment cadence, and pod count typically no longer matches by Q3, so the configuration gradually stops fitting the workload it was built for, without anyone noticing until the bill reflects it.
| Coverage | Automation Level | Conflict Risk | |
|---|---|---|---|
| HPA | Pod replica count | Reactive, metric-based | Can scale out on stale data while VPA resizes underneath it |
| VPA | Pod resource requests | Reactive, usage-based | Can resize requests mid-cycle without coordinating with HPA |
| Karpenter | Node provisioning and bin-packing | Reactive to unscheduled pods | Limited on its own; doesn’t fix oversized pod requests upstream |
| Zesty | Pod resource requests, Min replica counts and pod placement | Continuous and coordinated | Performs pod-level rightsizing and replica tuning itself, and consolidates nodes independently, so there’s no cross-controller conflict to manage |
Zesty’s Adaptive Pod Placement (APP) fills the gap Karpenter’s consolidation leaves on its own, continuously repacking pods onto fewer, better-utilized nodes as pods are added, resized, and removed, instead of waiting for a scheduled consolidation pass.
Phase 4: Cost Governance for the Long Term
Cost optimization decays without governance. A cluster rightsized and bin-packed this quarter drifts within one, because new workloads inherit whatever default requests a developer copies from an old deployment manifest, not the tuned values Phase 2 and Phase 3 established.
- Embed cost-aware defaults into Infrastructure as Code (IaC) templates (Terraform or CloudFormation modules) so every new cluster and workload inherits sane resource requests instead of copy-pasted guesses.
- Set budget alerts and anomaly detection on daily spend by namespace, so a misconfigured deployment gets caught within a day, not at month-end.
- Assign clear ownership, typically a FinOps or platform team, aligned to the AWS Well-Architected cost pillars, so cost decisions have an accountable owner instead of being everyone’s part-time job.
- Schedule automatic shutdown of non-production clusters and node groups during off-hours and weekends, since dev and staging environments rarely need to run 24/7.
Governance works best when it’s boring: alerts that fire automatically, defaults baked into shared modules, and a documented owner for every cluster, rather than a quarterly cost review that catches drift months after it started. The AWS Well-Architected Framework’s cost optimization pillar frames this as an ongoing operating model, not a project with a finish line, which is why Phase 4 never really ends the way Phases 1 through 3 can be considered done for a given quarter.
How do you keep EKS costs optimized long-term? Bake the rules into the infrastructure itself, alert on deviation immediately, and give someone explicit ownership, so governance doesn’t depend on anyone remembering to check. Zesty’s platform helps here too: because it continuously rightsizes and optimizes pod placement in the background, the gains from Phases 2 and 3 don’t require a governance team to actively re-enforce them week over week, only to make sure the guardrails around what it’s allowed to touch stay current.
Conclusion: Putting the Framework Into Practice
EKS cost optimization isn’t a single project with an end date. It’s audit, rightsize, automate, and govern, run in that order and then run again as the cluster changes. Teams that skip ahead, buying a pricing commitment before rightsizing or automating scaling before cleaning up orphaned resources, tend to land closer to 10-15% savings instead of the 40-60% the full sequence makes possible. The order matters because each phase produces the input the next one needs: audits establish the baseline rightsizing works from, rightsizing establishes the footprint automation scales correctly, and automation establishes the stable state governance is meant to protect. Reverse any of those dependencies and the phase downstream ends up working against incomplete or inaccurate information.
The catch is that manually executing all four phases, and then re-executing them every time traffic patterns shift, requires more continuous engineering time than most platform teams can spare on an ongoing basis. That’s the problem Zesty was built to automate. Zesty automates the full framework: it audits usage in real time instead of on a quarterly cadence, rightsizes pods and adjusts min replicas automatically as usage changes, optimizes pod placement to improve node utilization, and keeps governance intact as clusters evolve, so the savings from Phase 2 and Phase 3 don’t erode the way they do under manual management.
If your team is ready to automate EKS costs instead of re-running this framework by hand every quarter, Book a Demo with Zesty to see how it applies to your clusters specifically.
FAQs
What is EKS cost optimization and why does it matter?
EKS cost optimization is the practice of reducing what you spend running Amazon EKS clusters, mainly worker nodes, storage, and data transfer, without hurting reliability. It matters because most EKS bills run 30-50% higher than necessary, and that gap widens over time rather than shrinking on its own.
How much can you realistically save by optimizing an EKS cluster?
Teams that complete the full audit-rightsize-automate-govern sequence typically land in the 40-60% savings range. Teams that only tackle one or two phases, like rightsizing without governance, usually see gains erode within a quarter as new workloads reintroduce the same overprovisioning.
Should you rightsize before or after buying AWS Savings Plans?
Rightsize first. A Savings Plan discounts whatever capacity you lock in, so committing before rightsizing means paying a discounted rate on capacity you never needed. Rightsizing first, then buying the plan against the corrected baseline, captures both savings instead of just one.
What's the difference between HPA, VPA, and Karpenter for cost control?
HPA controls how many pod replicas run based on load. VPA adjusts how much CPU and memory each pod requests. Karpenter provisions and removes nodes to match what’s scheduled, including bin-packing workloads onto fewer nodes. All three need to be coordinated, since HPA and VPA can conflict when reacting to different signals at different times.
How does Zesty automate EKS cost optimization compared to manual tuning?
Manual tuning means someone periodically checks utilization and hopes the settings still fit by the next check. Zesty replaces that cadence with continuous automation: it rightsizes pods, adjusts minreplicas, and improves node utilization via Adaptive Pod Placement, so Phase 2 and Phase 3 gains hold without a recurring manual review.
Does rightsizing an EKS cluster risk hurting reliability?
Not if requests are set from observed p90-p95 usage with real headroom in the limits, rather than cut to the average. Risk comes from cutting too aggressively without re-validating under real load, not from rightsizing itself.
How long does the full audit-rightsize-automate-govern sequence take to complete once?
The audit alone typically takes one to two weeks for a mid-sized cluster. The full sequence through governance commonly runs 8-12 weeks end to end, though the audit and rightsizing phases deliver the bulk of the savings well before governance is fully in place.
