Skip to main content
rightsizing · azure

AKS node pools under 10% CPU that could run a smaller VM size

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

ZopNight flags an AKS node pool when node CPU averages under 10% across 30 days while memory stays below 50%, then prices the move to the next-smaller VM size in the same family from real hourly rates. Memory-bound pools and pools with no priced smaller SKU are never flagged.

Signal and threshold

How ZopNight evaluates AKS node pools under 10% CPU that could run a smaller VM size.
Field Value
Rule IDsRC-1357
Categoryrightsizing
Severitymedium
Metricnone — pure configuration read
Sourceaks_underutilized.go

Kubernetes hides idle nodes well

Cluster dashboards show pods, deployments, and namespaces, not the fact that every node in a pool is coasting at single-digit CPU. The bill, meanwhile, is driven entirely by the VM size and node count underneath. ZopNight reads the platform’s node-level CPU series for the agent pool; an average under 10% across the window marks the pool as provisioned well past its workload.

Memory is the veto that keeps this safe

Plenty of Kubernetes workloads are memory-hungry and CPU-light, JVM services being the classic case. A pool at 8% CPU but 70% memory is not oversized; it is memory-bound, and smaller nodes would evict pods. The rule therefore checks the full memory series and suppresses the finding whenever memory utilization reaches 50%. Crucially, this guard reads the entire harvested history, not a recent slice: a pool that ran memory-hot three weeks ago keeps its protection even if it cooled since. Disk utilization is attached as context but never gates.

Savings priced from the actual SKU ladder

The recommendation names the next-smaller VM size in the same family, so a Standard_D8s_v5 pool steps to Standard_D4s_v5. The dollar figure is the real hourly-rate delta between the two SKUs in your region, never a flat percentage. Both rates must be present in the pricing catalog, and SKUs that AKS restricts are filtered from the ladder. No nameable target or no rate means abstain.

Watch pool-level utilization directly

Terminal window
az monitor metrics list \
--resource "$(az aks show -n <cluster> -g <rg> --query id -o tsv)" \
--metric node_cpu_usage_percentage node_memory_working_set_percentage \
--interval PT1H --offset 30d --aggregation Average \
--filter "nodepool eq '<pool>'"

Acting on the finding

Two paths capture the saving: create a new pool at the smaller size and drain workloads over with node selectors, or reduce node count and let the cluster autoscaler enforce the floor. Watch pending pods and PodDisruptionBudget violations during the move.

What the detection needs

Reader and Monitoring Reader cover it; the CPU series must span at least 7 trustworthy days before any decision. ZopNight’s AKS write role can resize pools during scheduled windows, but this finding ships as advice, not automation.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·