Skip to content

What we measure ​

This page is the honest inventory. It exists because a cost tool that hides its gaps is worse than one that names them: if a dashboard shows $0 you cannot tell whether the answer is genuinely zero or the measurement is missing.

KubeSpend's rule is that an unknown renders as unavailable (null in the API), never as zero and never as an estimate.

Live and priced ​

DimensionHowConfidence
Node compute (on-demand)AWS Price List API, per region/instance/OS/tenancyExact list price
Node compute (spot)EC2 spot price history, newest sample per AZExact, as-of a timestamp
Per-pod / per-workload / per-namespace computenode price split 9:1 across vCPU:GiB, allocated by requestsExact given the split
Idle / unallocated capacitycluster cost minus attributed costExact
Node root volumes (EBS)Price List API per-GB-month, scaled by node-hoursVolume type assumed gp3
PersistentVolume storagePrice List API per-GB-month from PV inventoryGood
Rightsizing savingsreclaimed request × blended real node rateCeiling, not a guarantee
Instance/Graviton/spot/consolidation savingsreal Price List lookup for both current and candidateExact price delta

Approximate, and labelled as such ​

Data transfer rates come from a static table of us-east-1 list prices applied to every region, not from the Price List API. AWS models transfer as many inconsistently-named per-region SKUs, and cross-AZ traffic is not exposed as a single queryable product, so deriving it from the API would be guesswork. Responses report the source as a static table. Cross-AZ ($0.01/GB per direction) and NAT gateway ($0.045/GB) are uniform across commercial regions; internet egress varies by region and is the least accurate entry.

EBS IOPS and throughput rates are static constants. Only the per-GB-month storage price is fetched live.

Node root volume size is inferred from the node's ephemeral-storage capacity, which is the kubelet's view of the filesystem — slightly smaller than the provisioned volume. This underestimates rather than guesses.

Instance downsize utilization is cluster-level usage distributed across nodes proportionally by capacity, not per-node measurement.

Network: priced, with limits ​

What is priced. With the eBPF agent installed, each flow's ends are classified by zone and two buckets are priced per day, then folded into the cluster cost total:

  • cross-AZ (intra-region) transfer at a flat per-GB rate, counted per direction
  • internet egress on tiered rates, egress direction only

Same-AZ traffic is free and contributes nothing.

What limits it.

  • Cluster-level daily only. Network dollars land on the cluster's daily rows. Per-workload output is still bytes, split by zone.
  • Unclassified bytes are not priced. Where one end of a flow has no resolvable zone — internet peers, the EKS control plane, the API ClusterIP — the bytes are neither charged nor declared free, because either answer would be invented.
  • NAT gateway and inter-region are not modelled. The rates exist in the table, but nothing produces those buckets, so that spend is missing entirely.
  • networkUsd is null, never 0, when no flow records exist or when no region could be resolved for the cluster.

A standalone transfer-cost calculator is also available where you supply a GB figure yourself, for modelling scenarios the flow pipeline has no data for.

Read this before quoting a network number

A network figure is a floor, not the transfer bill. It covers cross-AZ and internet egress at the cluster level; NAT and inter-region are absent, and unclassified bytes are excluded. Check coverage.networkUnclassifiedBytes against coverage.networkPricedBytes before treating the number as complete. AWS network costs explains the charges.

Not implemented ​

  • Reserved Instances and Savings Plans amortization
  • NAT gateway and inter-region transfer cost (rates exist; nothing produces those buckets)
  • Per-workload network dollars — network cost is cluster-level and daily
  • Load balancer cost (rates exist; LB inventory is not collected)
  • HPA-based recommendations (HPA config is collected but unused)
  • Orphaned / unattached resource detection
  • IPv6, ICMP, SCTP and QinQ traffic in the eBPF path — IPv4 TCP/UDP only

When pricing is unavailable ​

A self-hosted server needs read-only AWS pricing credentials before it can price anything. Until they are configured, cost reads as unavailable and the response is flagged so the console can label it rather than draw a $0 chart. That is a configuration step, not a cheap cluster. SaaS is configured already.

Regions outside the supported set return an unsupported-region error rather than a fallback price.

Coverage on every response ​

Every cost response is qualified by how much of it could actually be measured:

  • how much of the requested window the agent reported for, and a partial flag below 95% coverage — meaning the reported cost understates actual spend
  • which node groups could not be priced, and are therefore excluded from the total
  • a complete flag, true only when nothing was unpriced and the window was essentially fully observed

See Coverage and confidence.

Every figure in KubeSpend traces to a real cloud price. Where we cannot measure something, we say so.