Kubernetes is a cost black box until you allocate it
The Lizrd team · · 2 min read
A Kubernetes cluster is the ultimate cost pooling machine. Dozens of teams land workloads on the same nodes, the invoice says “EC2,” and the answer to “what did the payments service cost last month?” is a shrug. That opacity isn’t a billing problem — it’s an ownership problem, and it’s why cluster spend drifts up quietly.
You can’t fix what you can’t attribute. So the first move in Kubernetes cost work isn’t rightsizing — it’s allocation.
The bill is nodes; the truth is requests
You pay for nodes. But nodes are just bin-packed pods, and the scheduler packs based on requests, not actual usage. That means a pod’s cost is its share of the node it reserved — its requests as a fraction of allocatable capacity — regardless of what it actually burned.
This is the insight most dashboards miss. A service requesting 4 vCPU and using 0.5 isn’t cheap because it’s idle; it’s expensive because it’s holding a seat on the node that nothing else can use. Allocation by request is what makes that visible.
Requests and limits are a cost decision
Most clusters carry enormous slack because requests were set once, by guesswork, and never revisited:
resources:
requests:
- cpu: "2"
- memory: "4Gi"
+ cpu: "500m"
+ memory: "1Gi"
limits:
memory: "1Gi"
Pull 30-day P95 CPU and memory per workload and the over-provisioning is stark. The rule is the same as any rightsizing: set requests to real peak plus headroom, not to a number that felt safe at 2 a.m. Every gigabyte of request you reclaim is a gigabyte the scheduler can pack, which is fewer nodes.
Bin-packing is where the nodes disappear
Once requests reflect reality, look at the pack. Fragmented nodes — 60% requested, unschedulable gaps — mean you’re paying for capacity no pod can use. Consolidation (via the Cluster Autoscaler or Karpenter draining underused nodes) turns that slack back into a smaller fleet. Right requests make good packing possible; good packing is what actually removes the nodes from the bill.
Attribution makes it stick
The technical wins evaporate without ownership. When per-namespace and per-label cost lands in front of the team that caused it — in the units they recognize — the conversation changes from “the cluster is expensive” to “our service is running 3x its request.” That’s the FinOps loop working: measured, owned, acted on.
Doing this by hand across a live cluster is tedious and perishable — workloads redeploy and the numbers move daily. We built Lizrd to keep it live: it reads your cluster utilization and cost together, allocates spend back to workloads and teams, and proposes the request or node-group change as an exact diff you can apply to EKS with confidence. A shared cluster stops being a black box the moment every pod has a price.