CostMonStart free

Calculator

Who is actually paying for your idle cluster?

Your cloud bill says $48,000 of EC2. Your cluster can't tell you who spent it. Drag in your real numbers to split that bill into used, workload idle, cluster idle, and system-reserved, then see who should actually pay for the idle.

Capacity, allocatable, requested, and used

Why the cloud bill can't tell you who spent it

An AWS, GCP, or Azure invoice bills by node: the instance type, the hours it ran, the region it ran in. Kubernetes doesn't bill anything; it schedules pods onto whatever node capacity is available and lets you set requests and limits per container. Those are two different accounting systems layered on top of each other, and nothing reconciles them automatically. The provider bill answers "what did the nodes cost," not "what did any given team, namespace, or workload actually spend." On a shared cluster, that second question is the one everyone actually wants answered.

This is why Kubernetes cost allocation is its own, harder problem than ordinary cloud cost monitoring: the unit you're billed for (a node, by the hour) and the unit you actually care about (a workload's fair share of that node) aren't the same unit, and the gap between them is where idle capacity hides.

Capacity ≠ allocatable ≠ requested ≠ used: the four numbers, and which one you pay for

A node's advertised capacity (say, 8 vCPUs) is never what's schedulable. The kubelet, the container runtime, the OS, and any DaemonSets running on every node all reserve a slice before a single application pod can be placed. What's left after that reservation is allocatable, and it's meaningfully smaller than capacity. From there, requested is the sum of every scheduled pod's CPU/memory requests: the amount the scheduler has promised, whether or not it's ever actually touched. And used is what those pods actually consume, measured continuously, which is very often a fraction of what was requested.

The bill is paid on capacity: every node, every hour, whether its allocatable slice is fully requested or empty. That's the whole reason this calculator exists: capacity is a fixed cost regardless of the other three numbers, and the gaps between capacity, requested, and used are the buckets it splits out below.

Requests vs. limits: the one is a bill, the other is a ceiling

A request is what the scheduler reserves on a pod's behalf. It's the number that determines whether a pod fits on a node at all, and it's the number this calculator's "requested" bucket is built from. A limit is a ceiling: the point at which the kubelet throttles CPU or OOM-kills the container, but it plays no part in scheduling and reserves nothing. Two pods with identical limits and wildly different requests get scheduled completely differently, and only one of them shows up in what a node can still fit.

That distinction matters for this page specifically because it's easy to assume a generous limit is "safe" and stop there. But a limit set high with no corresponding request just makes a node look more full than it is to a human eyeballing the manifest, while the scheduler only ever sees the request. Right-sizing that actually changes what a node can fit means changing requests, not limits.

Split the bill

See exactly where every dollar of the cluster goes

Enter the numbers you already have. Everything below computes in your browser — nothing you type here is sent anywhere.

Your bill
$24,000

The number already on your bill: the node group or compute spend for this cluster, before any right-sizing

40

How many nodes make up that bill

Node overhead
12%

kube-reserved + system-reserved + eviction threshold + DaemonSets: capacity every node loses before a single pod can schedule on it

CPU
65%

What your pods ask the scheduler to set aside for CPU

18%

What your pods actually use, on average (clamped to never exceed CPU requests)

Memory
55%

What your pods ask the scheduler to set aside for memory

30%

What your pods actually use, on average (clamped to never exceed memory requests)

Right-sizing scenario
25%

How much margin above actual usage the right-sized requests keep, so it protects against normal variance rather than sizing to a single average

80%

How tightly the scheduler bin-packs the new, smaller requests onto nodes

Idle-cost policy

How the idle pool (cluster idle + system-reserved) gets billed back to teams

Team request shares

Each team's share of total requests — normalized to 100% regardless of what these add up to.

40%
25%
20%
15%
Where the bill actually goesUpdates live
Live
At these numbersYou pay $24,000/mo. 15.8% of it does work.Every $1 of real compute costs you $6.31.

This cluster is CPU-bound — $2,112/mo of memory capacity is stranded behind the CPU request.

Used
$3,802 (15.8%)
Workload idle
$9,926 (41.4%)
Cluster idle
$7,392 (30.8%)
System-reserved
$2,880 (12%)

Right-size scenario

Today40 nodes$24,000/mo
Right-sized19 nodes$11,400/mo

Saves $12,600/mo$151,200/yr

Who pays for the idle?

TeamDirect costIdle shareChargebackIdle tax
Platform teamplatform
Product team A
Product team B
Product team C
Workload idle dominant

Your pods are asking for far more than they use.

Workload idle is the biggest bucket: capacity requested but never used. That's a request-sizing problem: pull actual P95 usage per workload and right-size requests down to it (a Vertical Pod Autoscaler can automate the recommendation), then re-run the scenario above with a headroom margin you're comfortable with.

See the right-sizing scenario above →
Start free

No vendor price table drives this — every dollar figure comes from your own inputs. Computes entirely in your browser; nothing typed here is sent anywhere.

Showback, tagging, the levers, and what CostMon does here

Who pays for the idle? Showback vs. chargeback, and the honest trade-off of each

Direct cost is a team's share of what's actually requested, and it's rarely the argument. The argument is the idle pool: cluster idle plus system-reserved capacity, the truly shared, unattributable cost nobody's workload specifically caused. Showback (reporting the number without billing it) and chargeback (actually billing it) both have to pick a policy for splitting that pool, and every policy this page models has a real, honest downside. There's no neutral option.

Proportional splits the idle pool by each team's share of requests. It's the default because it scales with size, but it punishes the biggest team hardest in absolute dollars even when the idle isn't disproportionately theirs. Even split divides the idle pool equally regardless of team size, which is fairer to the biggest team but can be a rounding error for a huge team and a painful line item for the smallest one. Platform-absorbs puts the entire idle pool on the platform/infra team's line, which keeps product teams' numbers clean but buries the idle in a cost center that has no lever over the product teams' actual request sizes. It hides the incentive to right-size instead of creating one.

None of the three is "correct": the right pick depends on whether the org wants idle cost to change behavior (proportional or even split, aimed at the teams that can actually act on it) or just wants a clean chargeback number for product P&Ls (platform-absorbs, at the cost of ever fixing the underlying idle).

Namespaces & labels: the tagging story for containers

Provider cost-allocation tags (an AWS cost allocation tag, a GCP label) live on the node or the resource. They don't know which pod, namespace, or team is running on that node at any given moment, especially once multiple workloads share it. Kubernetes has its own tagging layer: namespace, plus a `team`/`app`/`cost-center` label convention on pods. That's what actually maps spend to an owner inside the cluster, but it lives entirely outside what a provider's billing export can see.

That's the structural reason a provider bill and an in-cluster allocation view are two different systems that don't merge automatically: the provider knows the node's cost; only something reading inside the cluster (kubelet/cAdvisor metrics, namespace and label metadata) knows which workload that cost actually belongs to. A consistent labeling convention, enforced at manifest-review time rather than added after the fact, is what makes any allocation model attributable to a real owner instead of a guess. That includes the showback table above.

The levers, in the order that actually pays

Right-size requests first: it's the only lever with no infrastructure risk, and on most clusters it's also the biggest single bucket (workload idle routinely outweighs cluster idle on a cluster that hasn't been rightsized in a while). Rather than estimate that bucket with the sliders above, the Kubernetes Waste Analyzer reads your actual pod manifests and kubectl top output and names the specific workloads worth right-sizing first. Bin-pack and fix node shape second: once requests reflect real usage, a scheduler that's still spreading pods thin across too many nodes, or nodes shaped for the wrong resource ratio, leaves cluster idle on the table that right-sizing alone won't touch.

Autoscaling third: a cluster-autoscaler or Karpenter scale-down delay tuned too conservatively keeps nodes around long after load drops, which shows up as cluster idle that looks structural but is actually just a slow-to-react setting. Spot for the right workloads fourth: stateless, interruption-tolerant pods (batch, CI runners, fault-tolerant workers) are the cleanest fit for Spot's discount, and moving them off on-demand nodes frees the remaining on-demand footprint to be sized tighter.

Commitments on the stable floor fifth: once requests, packing, and autoscaling are tuned, whatever steady-state floor remains is what a Savings Plan or Reserved Instance should be sized against. And don't stop at compute: the storage and egress line items running through the same cluster are real costs hiding inside "the cluster" that none of the levers above touch. Think persistent volume claims, load balancer data processing, and cross-AZ pod-to-pod traffic.

What CostMon does (and doesn't do) here

CostMon reads the provider bill: your EKS, GKE, or AKS control-plane fee and node-group spend land in the same normalized daily view as every other provider you connect, with anomaly alerts on cluster cost drift the same way any other service's spend gets watched. That's the node-level, cross-provider half of the Kubernetes cost problem, and it's real coverage, not a teaser for a separate product.

CostMon does not run in-cluster, and it does not do pod- or namespace-level cost allocation. It can't see the requested-vs-used split this calculator models, because that data only exists inside the cluster's own metrics, not on a provider's billing export. That half of the problem needs the actual showback/chargeback numbers per namespace, computed continuously from live cluster data. For that, you want an in-cluster tool built for the job, like OpenCost or Kubecost.

Sources

Where the utilization stats on this page come from

Every figure above is attributed to a named primary source, re-verified live as of 2026-08-01. Vendor telemetry is labeled as exactly that — not asserted as an industry-wide fact.

  • Datadog — State of Cloud Costs

    83% of container cost is associated with idle resources: 54 points cluster idle, 29 points workload idle; and organizations use about 35% of EC2 compute spend running containers, up from 30% a year prior. This taxonomy is the calculator's model.

  • Datadog — State of Containers and Serverless

    Most workloads use less than half of their requested memory, and most consume less than 25% of their requested CPU.

  • CAST AI — 2026 State of Kubernetes Optimization Report

    Vendor telemetry from clusters that opted into an optimization product, collected before any automation ran: average CPU utilization ~8% (down from 10%), memory ~20% (down from 23%). Cited as vendor telemetry, not asserted as an industry-wide baseline, since the sample skews toward organizations already suspecting they're unoptimized.

  • AWS — Amazon EKS Pricing

    $0.10 per cluster per hour for standard Kubernetes version support. The control plane is nearly always the cheap part of an EKS bill next to the node group behind it.

FAQ

Common questions about Kubernetes cost allocation

Does this calculator need my actual Kubernetes metrics to work?

No, every input is a percentage or a dollar figure you already have a rough sense of (your bill, your node count, and approximate request/usage percentages from `kubectl top` or your metrics stack). It's a modeling tool, not a live integration, so an estimate is what it's built for.

What's the difference between workload idle and cluster idle?

Workload idle is capacity your pods requested but don't use: a request-sizing problem, fixed by right-sizing requests down to observed usage. Cluster idle is capacity that's schedulable but was never even requested by any pod: a packing/autoscaling problem, fixed by bin-packing, autoscaler tuning, and node shape. Same dollar-for-dollar waste, two completely different fixes.

Why does the binding resource matter?

Kubernetes schedules against whichever resource (CPU or memory) a pod's request pressures harder, node by node. The resource with the higher request percentage is what actually determines how many nodes you need. The other resource's slack is stranded behind it: it's capacity you're already paying for on every node, but it can't be reclaimed by shrinking the binding resource's requests alone, because node count is set by the binding one.

Why is the idle-tax multiplier sometimes shown as "—" instead of a number?

The idle-tax multiplier is monthlyBill ÷ usedCost: undefined, not infinite, when usedCost is exactly zero (0% actual usage). Rather than render `Infinity` or a divide-by-zero artifact, the calculator shows "—" for that one edge case; every other input combination renders a real, finite multiplier.

Which idle-cost policy should we actually use?

There's no policy without a trade-off. Proportional scales idle cost with team size but hits the biggest team hardest in absolute dollars. Even split is fairer to a large team but can be a painful, arbitrary hit to a small one. Platform-absorbs keeps product-team numbers clean but removes their incentive to ever fix the request sizing that's driving idle in the first place. Pick based on whether the goal is changing behavior or just producing a clean chargeback number.

Is the right-sizing scenario a guarantee of what we'll actually save?

No, it's a scenario, built from the usage percentages you enter plus a headroom margin and a target packing density, both of which you control. Real savings depend on whether the new, smaller requests actually re-pack the way the packing-density input assumes, and on autoscaler behavior actually scaling down to the new node count. Treat it as a sizing target to test, not a committed number.

Does CostMon replace Kubecost or OpenCost?

No. CostMon reads the provider bill: your EKS/GKE/AKS control-plane fee and node-group spend, normalized alongside every other provider you connect, with drift alerts on top. It does not run in-cluster and does not compute pod- or namespace-level allocation, which is what Kubecost and OpenCost are built for. The two tools answer different halves of the same question, and the page above links a full side-by-side comparison.

Where do the utilization statistics on this page come from?

Datadog's State of Cloud Costs report (83% of container cost is idle: 54% cluster idle, 29% workload idle; and about 35% of EC2 compute spend now runs containers) and its State of Containers and Serverless report (most workloads use under half of requested memory and under 25% of requested CPU) are both independent, published research. CAST AI's 2026 State of Kubernetes Optimization Report (average CPU utilization ~8%, memory ~20%) is vendor telemetry from clusters that opted into an optimization product, which skews toward unoptimized baselines. It's cited here as vendor telemetry, not as an industry-wide fact.

The meter you don't watch still grows.

Waste rarely hides in the service you check every week. CostMon watches every meter on your stack, including the ones you forgot were running.

Esc