# Running EKS Node Group Idle

> Worker nodes bill full instance-hours whatever their pods do, so a node group whose CPU averages and peaks under 3% for 30 straight days is capacity bought for nothing. ZopNight also vetoes on memory, since a CPU-quiet group holding large caches must not be torn down, and prices the entire run-rate as recoverable.

Source: https://zop.dev/integrations/aws/recommendations/running-eks-node-group-idle
Updated: 2026-08-19

---

## The 3% bar, and why it is not zero

Real nodes are never at literal zero: kubelet, system daemons, and the container runtime
produce a permanent murmur of CPU. The idle floor sits at 3%, comfortably above that
baseline and far below any workload, and both the 30-day average *and* the peak must stay
under it. A group that bursts weekly above the floor is being used, however idle it looks
between bursts, and abstains.

## Memory can veto what CPU approves

A node group can be CPU-silent while holding memory that matters: in-memory caches, JVM
heaps, stateful sets that do their work in RAM. Tearing that down evicts state the surviving
capacity cannot absorb. So the memory rollup is required alongside CPU with the same 30-day
coverage, and a memory-loaded group abstains even at 0% CPU. Both series come from [the CloudWatch Observability EKS add-on](https://docs.aws.amazon.com/eks/latest/userguide/cloudwatch.html); clusters without the agent produce no rollups, and the
rule stays silent on them rather than tearing down capacity it cannot see.

## How the dollar figure is built

The node group object itself is free (the money is in its EC2 workers), so the run-rate is
priced directly: the node's [live on-demand hourly rate](https://aws.amazon.com/ec2/pricing/) × 730 hours × the desired node count,
fully recoverable on teardown. Two pricing abstentions follow. No resolvable rate means no
recommendation. And Spot groups abstain entirely: only the on-demand rate is visible to the
rule, and pricing a removed Spot node at on-demand would overstate the saving roughly 2–3×.

## What this rule leaves to its siblings

Groups already scaled to zero, and degraded groups, belong to the abandoned-workloads rule;
unhealthy or transitioning groups are skipped so a teardown is never recommended mid-repair.
Only healthy, active groups with at least one desired node land here.

## See the rollup yourself

```bash
aws cloudwatch get-metric-statistics \
  --namespace ContainerInsights --metric-name node_cpu_utilization \
  --dimensions Name=ClusterName,Value=my-cluster Name=NodegroupName,Value=my-nodegroup \
  --start-time "$(date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)" \
  --end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --period 86400 --statistics Average Maximum
```

Before acting, check for seasonal or intermittent jobs that schedule onto this group, drain
with PodDisruptionBudgets in place, and sweep for load balancers and EBS volumes the group
leaves behind. Those keep billing after the nodes are gone.
