All posts
Kubernetes

EKS Spend Control: Where Kubernetes Money Leaks, and How to See It Per Team

By

November 2, 2026

7 min read

EKS bills are mostly nodes, and nodes are sized by what pods request, not what they use. The leaks we find most (inflated requests, half-empty nodes, cross-AZ chatter, one load balancer per service, clusters on extended support) and how split cost allocation data puts a price on every namespace in the Cost and Usage Report.

EKS Cost
EKS
FinOps
Karpenter
Cost Optimization

The EKS control plane is $0.10 an hour, about $73 a month. Almost everything else on a Kubernetes bill is EC2, and EC2 is bought for what pods request. A pod that requests 2 vCPU and uses 0.2 still holds a node's capacity, and the scheduler packs nothing else into the gap.

The leaks, in the order we usually find them

Leak

How to see it

Fix

Requests far above usage

Compare requested CPU and memory with actual usage per workload

Right-size requests from a week of usage; keep limits for memory, rarely for CPU

Half-empty nodes

Node utilization below ~50% for days

Karpenter or Auto Mode consolidation; fewer, larger instance types where pods are small

On-demand everything

No Spot capacity in node pools

Spot for stateless, interruptible workloads, with on-demand as fallback

x86 by habit

Instance families in use

Graviton (Arm) node pools for workloads with Arm images

Cross-AZ traffic

DataTransfer-Regional-Bytes in Cost Explorer

Topology-aware routing; keep chatty services in the same zone; $0.01/GB each way adds up

A load balancer per Service

Count of ALBs and NLBs

One ALB shared through an ingress group or Gateway API

Extended support

Clusters on a Kubernetes version past standard support

Upgrade: $0.60 an hour instead of $0.10, about $438 a month per cluster instead of $73

Idle environments

Dev and preview namespaces running at night and weekends

Scale to zero on a schedule

Logs

CloudWatch ingestion by log group

Drop debug logs in production; infrequent-access log class for what you keep

Want a second opinion on this for your system?

Book a free 30-minute call. You'll leave knowing what we'd do first and roughly what it costs, whether or not you hire us.

Putting a price on every team

Split cost allocation data adds pod-level rows to the Cost and Usage Report: each pod's share of its node's amortized cost, based on the CPU and memory it reserved, and for GPU and Trainium or Inferentia instances, the accelerators too. It creates cost allocation tags for the cluster, namespace, node, workload and deployment (aws:eks:namespace and friends), enabled by default.

  • Turn it on in the Billing console for the CUR, then query cost by namespace in Athena.

  • Expect volume: two new rows per pod per hour (three on accelerated instances). A thousand short-lived pods an hour is about 48,000 rows a day.

  • Unallocated capacity (the gap between what pods reserve and what nodes cost) is the number to watch. It is the bin-packing waste, and it belongs to the platform, not to any team.

Guardrails that keep it fixed

  1. LimitRanges and ResourceQuotas per namespace, so a new service can't request a whole node by accident.

  2. A weekly report of the top ten workloads by requested-minus-used, sent to their owners.

  3. Budgets per namespace from the split cost data, with alerts at 80%.

  4. An upgrade calendar so no cluster drifts into extended support.

hoolco Monthly Review

Once a month: what changed in tech that month and what it means for you, from cloud and AI to security and the tools you build with. Every item links to its source. No sales pitch, unsubscribe in one click.

As of November 2, 2026. Provided as is, for general information, and accurate to the best of our knowledge on the date shown. Not legal, compliance, tax, financial or other professional advice. Prices, limits and vendor services change; check current vendor documentation before relying on anything here. Terms of use.