By Raúl Pérez · Last updated: October 2026 · Reading time: 11 min
Your cloud invoice says the Kubernetes cluster cost $48,000 last month. Useful? Not really. The questions engineering leaders actually ask are: which team spent it, which namespace is the most expensive, which workloads are mostly idle, and is it getting better or worse? A cloud bill cannot answer those, because it sees nodes and disks, not namespaces and deployments.
That gap is what Kubecost fills. In this tutorial you will install Kubecost, connect it to your cloud billing data, read the namespace views, query costs through the API, set up alerts and budgets, and turn the data into a showback process that engineers will actually use.
What Kubecost Does (and How It Calculates Cost)
Kubecost is a Kubernetes cost monitoring and optimization tool built on top of OpenCost, the CNCF open-source cost allocation engine. It combines three data sources:
- Kubernetes metadata: namespaces, pods, labels, controllers, PersistentVolumeClaims.
- Resource usage and requests: CPU, memory, GPU, storage and network, collected through Prometheus.
- Pricing: either public list prices, or your actual negotiated rates and discounts through cloud billing integration.
For each pod it determines the cost of the node it ran on, then allocates a share based on the resources the pod used or requested (generally the greater of the two). Add up pods per namespace, label or controller and you get cost per namespace, team or application.
Some definitions you will see everywhere in the interface:
- Allocation: cost assigned to Kubernetes objects such as namespaces and deployments.
- Assets: the underlying infrastructure: nodes, disks, load balancers.
- Idle cost: cost of capacity that is not allocated to any workload.
- Efficiency: how much of what workloads requested they actually used.
- Shared cost: costs that benefit everyone (for example
kube-system, monitoring) that you may want to split across teams.
Features, tiers and chart parameters change between versions, so use the official Kubecost documentation as the final reference for exact options.
Prerequisites
- A running Kubernetes cluster (EKS, AKS, GKE or self-managed) and
kubectlaccess. - Helm 3 installed.
- Permissions to create a namespace and cluster-scoped RBAC resources.
- Enough spare capacity for Kubecost’s components. A small cluster typically needs a few hundred millicores and one to a few GB of memory for Kubecost and its bundled Prometheus, depending on cluster size and retention.
If you already run Prometheus, Kubecost can use it instead of its own bundled copy. Check the documentation for the required metrics and scrape configuration.
Step 1: Install Kubecost With Helm
helm upgrade --install kubecost cost-analyzer \
--repo https://kubecost.github.io/cost-analyzer/ \
--namespace kubecost --create-namespace
Check that the pods are running:
kubectl get pods -n kubecost
Then access the dashboard through a port-forward:
kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 9090
Open http://localhost:9090 in your browser. It can take from several minutes to a few hours before charts show meaningful data, because Kubecost needs time to collect usage. Some features, such as longer retention or multi-cluster aggregation, may require a free token or a paid tier. Confirm what is included in your version.
For anything beyond a trial, do not leave the dashboard open. Expose it through an internal ingress with SSO, or keep it behind a VPN.
Step 2: Connect Cloud Billing for Real Prices
Out of the box, Kubecost estimates costs using public on-demand prices. That is a fine start, but it will not match your invoice if you use Spot instances, Savings Plans, reservations, enterprise discounts or credits. To fix this, connect your cloud billing data.
- AWS: set up a Cost and Usage Report (CUR) delivered to S3, plus Athena integration, and give Kubecost read access through an IAM role.
- Azure: export cost data to a storage account and provide Kubecost with read access.
- GCP: enable the BigQuery billing export and provide access.
The exact integration steps differ by cloud and Kubecost version, so follow the provider-specific guide in the official docs. After the integration, Kubecost can reconcile its estimates with real billed amounts, which makes namespace costs match what finance sees.
A practical test: compare the total Kubecost shows for the last full month with the cluster’s cost in your cloud billing console. A small gap is normal (shared services, taxes, credits, data lag). A large gap usually means the integration is incomplete.
Step 3: Read the Namespace Costs in the Allocations View
In the Kubecost UI, open Allocations. This is the view you will use most.
- Set the window to
Last 7 daysorMonth to date. - Set Aggregate by to
Namespace. - Set Resolution to daily, so you can see trends.
- Toggle between Cumulative and Daily to spot spikes.
For every namespace you will see a breakdown of CPU, memory, persistent volumes, network, load balancers and shared cost, plus an efficiency percentage. How to read it:
| Signal | What it means | What to do |
|---|---|---|
| High total cost, high efficiency | Big but well used | Probably fine, look at unit cost |
| High total cost, low efficiency | Requests far above usage | Right-size requests first |
| Low usage, high idle share | Cluster sized beyond need | Consolidate nodes or scale down |
| Sudden daily spike | Deployment, loop or leak | Check recent releases and autoscaling |
| Persistent volume cost growing | Data or orphaned volumes | Review PVCs and retention |
Click any namespace to drill down into its controllers, pods and containers. The most expensive deployment in the most expensive namespace is often a better starting point than a cluster-wide initiative.
Aggregate by more than namespace
Namespaces are only one dimension. Switch Aggregate by to:
- Label (for example
team,app,env,cost-center) - Controller or Deployment
- Service
- Pod
- Cluster, if you run several
If a team owns multiple namespaces, aggregating by a team label gives the right chargeback unit. This is why a consistent labeling scheme matters, covered next.
Step 4: Fix Your Labels So Costs Map to Teams
Kubecost can only attribute what Kubernetes metadata tells it. Standardize labels on namespaces and workloads:
apiVersion: v1
kind: Namespace
metadata:
name: payments-prod
labels:
team: payments
env: prod
cost-center: cc-4410
apiVersion: apps/v1
kind: Deployment
metadata:
name: checkout-api
labels:
app: checkout-api
team: payments
spec:
template:
metadata:
labels:
app: checkout-api
team: payments
Remember that labels must be on the pod template, not just the Deployment metadata, for them to reach pods. Enforce the scheme with an admission policy (Kyverno or OPA Gatekeeper), and review an “unallocated” or “unlabeled” line in Allocations each week to catch gaps.
Step 5: Handle Idle and Shared Costs Fairly
Two settings change namespace totals more than anything else.
Idle cost. Capacity on nodes that no pod claims. You can show it as its own line, or share it across namespaces proportionally. Sharing idle makes namespace totals add up to the full cluster bill. Showing it separately highlights waste at the platform level instead of blaming individual teams. Many organizations show idle separately first, then share it once teams have had time to optimize.
Shared namespaces. Cluster-wide services such as kube-system, ingress controllers, service meshes and monitoring benefit everyone. Configure these as shared costs, split evenly, proportionally to usage, or by weighted rules, so they do not distort one team’s bill.
Whatever you choose, write the policy down and tell teams how numbers are computed. Disputes over methodology kill showback programs faster than any technical problem.
Step 6: Query Namespace Costs Through the Allocation API
Dashboards are great for exploration, but automation needs an API. With the port-forward running, query costs per namespace for the last seven days:
curl -G http://localhost:9090/model/allocation \
-d window=7d \
-d aggregate=namespace \
-d accumulate=true \
-d includeIdle=true \
| jq '.data[0] | to_entries[] | {namespace: .key, totalCost: .value.totalCost, cpuEfficiency: .value.cpuEfficiency, ramEfficiency: .value.ramEfficiency}'
Aggregate by a label instead:
curl -G http://localhost:9090/model/allocation \
-d window=month \
-d aggregate=label:team \
-d accumulate=true
Use these endpoints to:
- Post a weekly cost summary to Slack.
- Feed a data warehouse or Grafana.
- Fail a CI check when a preview environment’s cost exceeds a limit.
A small script is enough to start:
import requests
r = requests.get("http://kubecost.internal/model/allocation", params={
"window": "7d", "aggregate": "namespace", "accumulate": "true"
})
rows = r.json()["data"][0]
top = sorted(rows.items(), key=lambda kv: kv[1]["totalCost"], reverse=True)[:10]
for ns, v in top:
print(f"{ns:30s} ${v['totalCost']:.2f} cpuEff={v.get('cpuEfficiency', 0):.0%}")
Endpoint names and response fields can vary by version. Check the API reference for the release you run. If you only use OpenCost, it exposes a similar allocation endpoint with its own parameters.
Step 7: Set Up Alerts, Budgets and Reports
Real-time visibility only helps if someone gets notified. Kubecost supports several mechanisms (availability depends on edition and version):
- Budget alerts: notify when a namespace, label or cluster exceeds a spend threshold in a time window.
- Efficiency alerts: notify when a namespace’s efficiency stays below a target.
- Spend change alerts: flag unusual increases versus a baseline.
- Recurring reports: scheduled summaries by email or Slack.
A simple, effective configuration:
| Alert | Scope | Threshold | Audience |
|---|---|---|---|
| Monthly budget warning | Each production namespace | 80% of monthly budget | Team channel |
| Spend spike | Whole cluster | +25% week over week | Platform team |
| Low efficiency | Namespaces over $500/month | CPU efficiency below 30% | Namespace owner |
| Weekly digest | Top 10 namespaces | Every Monday | Engineering managers |
Pair these with Kubernetes ResourceQuotas, which cap what a namespace can request, so a budget alert has a technical limit behind it.
Step 8: Turn Findings Into Savings
Once namespace data is flowing, work through the Savings or recommendations section and the efficiency columns:
- Right-size requests. Compare requested and used CPU and memory per container and lower requests where usage is consistently far below. See our guide on [preventing cloud waste caused by over-provisioned pods and CPU limits].
- Remove abandoned workloads. Look for namespaces and deployments with near-zero usage for 30 days.
- Clean unused volumes and load balancers. Orphaned PersistentVolumes and idle load balancers appear as asset costs.
- Consolidate nodes. If idle cost is high after right-sizing, use Karpenter or Cluster Autoscaler tuning to shrink the cluster. See [Karpenter vs Cluster Autoscaler: Cost Efficiency Comparison].
- Move suitable workloads to Spot. Kubecost can show which workloads are good candidates because they are stateless and replicated.
- Reduce non-production cost. Compare
env=devandenv=stagingcosts, then schedule shutdowns.
Record the cost of a namespace before and after each change so you can prove the savings.
Step 9: Build a Namespace Showback Process
Tooling is the easy half. The habit is what lowers costs. A lightweight, repeatable process:
- Weekly: automated report to each team with namespace cost, trend and efficiency.
- Monthly: a 30-minute review of the top 10 most expensive and top 10 least efficient workloads with their owners.
- Quarterly: revisit budgets, shared cost rules and commitments.
- Always: publish a unit metric such as cost per 1,000 requests or per active customer, so growth is not mistaken for waste.
Start with showback (informing teams) before chargeback (moving money between budgets). People accept numbers much more readily after they have seen them for a few months.
Kubecost vs OpenCost: Which Should You Use?
OpenCost provides the open-source core: allocation, pricing and an API, free and vendor-neutral. Kubecost builds a richer product on top, with a UI, savings recommendations, alerts, reports, multi-cluster views and enterprise features. A common path is to start with OpenCost, move to Kubecost when you need the extras, and compare both against your needs. We break it down in [OpenCost vs Kubecost: Which Open-Source Tool Wins?].
Common Problems and Fixes
| Problem | Likely cause | Fix |
|---|---|---|
| Dashboard is empty after install | Prometheus still collecting data or failing to scrape | Wait, then check pod logs and Prometheus targets |
| Costs do not match the cloud bill | No billing integration, or missing discounts | Connect CUR, billing export or BigQuery export |
Many costs show as __unallocated__ | Missing labels or short-lived pods | Enforce labels, check pod template labels |
| Namespace totals are lower than the invoice | Idle and shared costs excluded | Include idle, configure shared namespaces |
| High memory use by Kubecost itself | Large cluster or long retention | Tune retention, use an external Prometheus or the recommended storage |
| Data gaps | Prometheus restarts or limited storage | Add persistent storage and monitor Prometheus health |
Frequently Asked Questions
Is Kubecost free? There is a free tier with core cost allocation for a limited scope, and paid tiers with additional features such as longer retention and multi-cluster aggregation. Limits change, so check the current pricing and licensing page.
How real-time is Kubecost? Usage metrics update on a short interval, but billing-reconciled costs follow the cloud provider’s data delay, which can be hours or up to a day or more.
Can Kubecost track costs across multiple clusters? Yes, with a multi-cluster setup, typically requiring a paid tier and shared storage. Check the documentation for architecture details.
Does Kubecost work on EKS, AKS and GKE? Yes, it supports all three plus self-managed clusters, with provider-specific billing integrations.
Does Kubecost cause performance overhead? It adds resource usage, mostly through Prometheus. For small clusters it is modest. For large clusters, size Prometheus and retention carefully.
Conclusion
Tracking namespace spending turns Kubernetes from an opaque shared cost into something teams can own. Install Kubecost, connect real billing data, standardize labels, decide how to treat idle and shared costs, and pipe the numbers into alerts and weekly reports. Then act on the efficiency data: right-size, clean up, consolidate and automate. The savings come from the loop, not the dashboard.
