Kubernetes namespace cost allocation splits the cost of a cluster's nodes across namespaces and labels by way of the pods: each pod receives a share of its node's cost, measured by requests, usage or the greater of the two, and namespaces and labels add those shares up to teams, products or environments. On clusters billed per node, the provider charges for nodes, not pods; the data sources are covered in Kubernetes cost data. It matters for the bill because the same invoice produces different team totals depending on three decisions (unit, basis, remainder), and because the part no pod claims lands with nobody unless a rule assigns it.

How it works

The unit: namespace, label or workload

A namespace divides a cluster's resources between users. Every namespaced object lives in exactly one namespace. Nodes, persistent volumes and storage classes belong to no namespace, so their cost reaches a namespace only through the pods that use them. Within a namespace, labels tell resources apart.

Three units follow from that. The namespace works when it belongs to exactly one team. A team or product label on the pods is needed when several teams share a namespace. The workload (Deployment, StatefulSet, Job) shows the cost of individual services. The namespace-to-team mapping is not in the billing data but a table or namespace label, maintained like any other segment. Pod labels reach the reports as tags. GKE writes them into the export as k8s-label/ followed by the key. On AWS, split cost allocation data imports up to 50 pod labels per pod (the first 50 in alphabetical order) as user-defined cost allocation tags, which the management account has to activate, and adds its own tags such as aws:eks:namespace and aws:eks:workload-name. For them to match the rest of the tags and labels, label keys follow the same tagging policy.

The basis: requests, usage or the greater

A request reserves capacity. The scheduler places a pod only on a node where the sum of requests stays below capacity, even when actual utilisation is low. A container may use more than it requested while the node has room; the kubelet enforces limits, and where only a limit is set, Kubernetes uses it as the request.

BasisWho uses itWhat it assumesWhere it breaks
RequestsGKE cost allocation; AWS with the Resource requests optionreserved capacity is consumed, even when it sits unusedpods without requests receive no cost; usage above the request is not charged to the pod
Greater of request and usagethe OpenCost specification; AWS with usage metrics from Amazon Managed Service for Prometheus or Amazon CloudWatch Container Insightsthe reservation and any extra usage are both paid forneeds usage metrics; team totals move with load peaks

On accelerated computing instances (GPU, Trainium, Inferentia) AWS always allocates by requests, whichever option was chosen.

A node has one price, not a price per vCPU and per gigabyte. For split cost allocation data, AWS weights vCPU and memory 9:1, derived from AWS Fargate's prices per vCPU hour and per GB hour. The OpenCost specification recommends per-resource prices in the ratio of the instance family's marginal rates, normalised to the node's price, with the fully amortized net cost as input. AWS also works from the instance's amortized cost.

The remainders: idle, system and shared cost

The OpenCost specification puts the split into two equations: asset cost equals workload plus idle cost, and total cluster cost adds overhead such as cluster management fees. Idle cost is the part of time-based cost that no workload claims; anything billed purely on usage is never idle. Beside it sit system overhead (capacity each node holds back for the kubelet, container runtime and other system processes, and system workloads such as kube-system), shared cluster cost (cluster fees, load balancers, monitoring) and cost the tool cannot assign to any namespace. AKS System charges and GKE's kube:system-overhead cover only the capacity reserved on each node; system workloads such as kube-system run as pods in a namespace of their own.

RemainderAWS split cost allocation dataAKS cost analysisGKE cost allocationOpenCost
Idlesplit_line_item_unused_cost, shared out per podIdle chargeskube:unallocated__idle__
System overheadno column of its ownSystem chargeskube:system-overheadsystem workloads as shared cost
Service and clusteroutside the split dataService charges, such as the Uptime SLAoutside the supported SKUsoverhead
Unassignablepods without requests under the Resource requests optionUnallocated chargesgoog-k8s-unknown, goog-k8s-unsupported-skunot specified

Each remainder first stays visible as its own line, then an agreed rule assigns it. The OpenCost specification names three methods for shared cost: evenly across tenants, in proportion to their share of asset cost, or by a custom metric such as network egress. The OpenCost API spreads idle with shareIdle in proportion to each allocation's other cost, separately per resource and either per cluster or per node. AWS already distributes an instance's unused capacity to the pods that ran on it, but keeps it in a column of its own beside the split cost.

What it means for your cost

The basis shapes how teams behave. Allocated by requests, a team carries what it reserves and lowers its cost only by lowering its requests. Allocated by the greater of the two, it also pays for peaks above its request. The basis is therefore an allocation rule like any other, dated and not switched quietly mid-year.

The report carries one line per namespace or team, plus one each for idle, system overhead, shared cluster cost and unassignable cost; together they add up to the cluster's cost on the invoice in the same cost view. AKS views show actual cost unless switched to amortized, while AWS split data is amortized; mixing them compares different views. As its own line, idle stays with the cluster's owner and shows how much paid capacity nobody requested. Idle and orphaned resources covers whether it can be removed, virtual machines and instance families and containers and Kubernetes what nodes and clusters cost, shared cost the split keys, and unallocated cost whatever is left after every rule.

Where it goes wrong

  • Idle disappears into team totals. Symptom: the teams together carry exactly the cluster's cost, but nobody sees the unused capacity. Cause: idle is spread (with shareIdle in OpenCost, or by adding the unused cost on AWS) before it appears as its own line.
  • One namespace for several teams. Symptom: a namespace carries high cost and no team recognises it as its own. Cause: several teams share the namespace and the pods carry no team label.
  • Labels get lost on the way. Symptom: in the GKE export or the CUR some pods lack their team label, or sidecar cost sits under kube:unallocated. Cause: GKE drops every label of a pod that has more than 50, and does not attribute native sidecar requests to the namespace; AWS imports only the first 50 labels in alphabetical order and shows none until they are activated.
  • Autoscaling produces unknown lines. Symptom: in months with heavy scaling, lines labelled goog-k8s-unknown appear. Cause: GKE cannot attribute lines while nodes start and stop, as during autoscaling.

Sources

Read on 2026-10-16. OpenCost OpenCost Specification and API; Kubernetes resource management for pods and containers and namespaces; AWS understanding split cost allocation data, enabling split cost allocation data, using split cost allocation data with Amazon CloudWatch Container Insights, using Kubernetes labels for cost allocation in EKS, example of split cost allocation data and split line item columns; Microsoft Azure Kubernetes Service (AKS) cost analysis and view Kubernetes costs; Google get key spending insights for your GKE resource allocation and cluster costs.