Kubernetes - How Finout Calculates K8s Costs

Overview

Kubernetes is an abstraction layer over your infrastructure that orchestrates resources and manages their lifecycles. At the base of Kubernetes, there are containers, which package your application’s code and dependencies. Containers are grouped into pods, the smallest deployable units in Kubernetes. Pods are grouped into workloads (deployments, statefulsets, or cronjobs), which define how your application runs and scales, adding business context by connecting each pod’s purpose to its broader goal.

Each workload operates within a namespace, which serves as a logical scope that groups related workloads and resources, providing isolation, naming, and policy for environments, teams, or applications. Underneath these logical layers are the physical resources that Kubernetes manages: nodes (individual servers) and clusters (collections of nodes). Kubernetes orchestrates this entire stack and maintains the desired application state, ensuring availability.

The Challenges of Kubernetes Costs

Kubernetes cost allocation presents a unique challenge in cloud financial management. Unlike traditional cloud vendor billing, where costs are directly tied to specific resources, Kubernetes abstracts away the underlying infrastructure, making it difficult to attribute costs to individual pods, namespaces, deployments, and applications.

Finout’s Solution

Finout solves this challenge by combining Kubernetes request, usage, network metrics, with actual cloud billing data, transforming Kubernetes into a fully integrated cost center within your financial management framework. This integration ensures that Kubernetes cost data is available across Finout, just like any other cloud provider.

By treating Kubernetes as a standard cost center, users can leverage Finout's powerful cost management tools to address shared cost allocation and idle resource challenges effectively.

High-Level Calculation Process

Finout combines cloud billing data with Kubernetes metrics to accurately distribute node costs across Kubernetes abstractions based on resource consumption.

  1. Collect Metrics: Finout gathers CPU and memory request and usage metrics, as well as network metrics from Kubernetes through its native integration with Prometheus or Datadog, providing the foundation for accurate cost allocation and optimization.

  2. Parse Unit Metrics: Finout identifies allocatable usage metrics per pod from raw Kubernetes data.

  3. Collect Node Costs: Finout retrieves node costs from the cloud provider's billing.

  4. Apply Finout's Kubernetes Cost Algorithm: Finout determines the resource’s CPU, Memory, and Network allocation and distributes the node costs accordingly.

  5. Idle Calculation: Calculates and allocates costs for unused capacity.

Step 1: Query the Metrics

Finout reads Kubernetes metrics from your connected source (Prometheus or Datadog) and uses them as the foundation of the Kubernetes cost calculation.

Finout gathers per pod CPU, Memory, and Network metrics. These metrics provide the basis for parsing the usage metrics per pod in step 2.

Note: The data is sampled at a one-minute resolution every 30 minutes, with the 30-minute interval being configurable per account.

Step 2: Allocate the Metrics

Finout processes the collected Kubernetes metrics and assigns them to their respective pods, generating hourly usage and request hourly metrics allocations per pod. This allocation is then used to calculate pod costs in step 3.

CPU & Memory

  • Finout uses hourly Kubernetes metrics to calculate resource allocations for each pod, separately for CPU (cores) and memory (GiB). These allocations are later used to determine pod costs.

  • It reflects engineering intent (requests) and actual consumption (usage) to avoid under- or over-allocation.

  • For each hour, the CPU/Memory metrics allocation is based on the larger value between the pod’s usage and the pod’s request.

  • It’s capped at the node’s capacity, thereby excluding any pending pods or nodes.

Network

  • Finout uses Kubernetes metrics to measure bytes received and bytes sent per pod (per hour), providing network usage context alongside CPU and memory.

For Example:

  • Hour A: CPU request peaks at 3 cores in a certain hour, CPU usage peaks at 1 core in the same hour → hourly CPU allocation = 3 cores.

  • Hour B: CPU usage peaks at 4 cores (above request) → hourly CPU allocation = 4 cores.

  • The same “larger value of usage or request” rule applies to Memory (GiB) each hour.

Step 3: Get the Hourly Price per Cloud Resource (Node)

Finout takes the node’s resource cost directly from your cloud billing and uses it as the price to be allocated later across the Kubernetes abstractions (namespaces/workloads).

  • Billing-sourced price: Finout reads vendor’s billing exports (e.g., AWS CUR) to get the exact node $/hour.

  • Discount-aware: Finout considers Savings Plans, RIs, Spot, and EDP (when applicable), so the price reflects your real effective rate.

  • Purpose: This node's hourly price is used in the rest of the calculations.

Step 4: Calculate the Pod Costs

To calculate the cost of a pod, Finout uses the hourly CPU, memory, and network metrics allocations (step 2), along with the hourly node cost (step 3), to determine the pod's CPU and memory cost, respectively.

The hourly pod cost is reported as the total cost of the allocated CPU and memory within an hour. The problem is that the cloud provider does not provide billing data in this granularity, nor a CPU/memory cost breakdown. To apportion the node costs to CPU and memory costs in the pod level correctly, Finout specifies a configurable CPU/memory ratio applied in cost calculation algorithm for each resource, workload, cluster, or namespace.

Note: Finout calculates Kubernetes costs at the pod level, based on each pod’s CPU and memory allocations. These calculations are then aggregated at the workload level (such as Deployments, CronJobs, and StatefulSets) and reflected in the MegaBill. This approach presents cost data in a meaningful business context rather than at the overly granular pod level.

Compute Costs

Calculation Process Overview:

  1. Inputs: Hourly Node Price ($/hour) from the cloud vendor billing + per-pod hourly CPU/Memory allocations.

  2. CPU:Memory ratio and algorithm: This defines how node costs are split between CPU and Memory, and how the pod cost is calculated accordingly. There are two types of algorithms: Recommended and Legacy. Recommended algorithm: Based on a 88:12 CPU:Memory default ratio.

    • Starting November 2024, the Recommended algorithm is the default for all new accounts.

    • The default CPU:Memory ratio is configurable per account. To change it, contact [email protected].

    Legacy algorithm: Based on a 50:50 CPU:Memory default ratio.

    • Accounts created before November 2024 use the Legacy algorithm by default. To migrate to the Recommended algorithm, contact [email protected].

    • The default CPU:Memory ratio is configurable per account. To change it, contact [email protected].

  3. Derive CPU/Memory unit prices at the node level: Compute the price of one CPU core and one GiB for that hour (for the entire node).

  4. Price for each pod: Multiply unit prices by the pod’s hourly CPU and Memory allocations, then sum them to get the hourly pod price.

    Note: For AKS cost calculation (Azure), the calculations are performed on a daily granularity, not an hourly granularity.

The recommended Kubernetes cost algorithm uses an 88:12 CPU:Memory ratio by default for a more precise cost allocation, reflecting real-world usage where CPU is usually more expensive than memory.

Hourly Pod Cost: Hourly Pod Cost is calculated by multiplying the number of allocated CPUs by the hourly CPU cost, as well as the amount of allocated memory by the hourly memory cost, and then adding these two results.

The pod's hourly pricing using the recommended algorithm is calculated using the following formulas:

  1. Hourly Pod CPU Allocation: Hourly pod CPU allocation is used to determine how much of the node’s CPU was allocated. This is based on the greater value of the average hourly CPU usage or the average hourly CPU request. See the full explanation about parsing the metrics per pod in step 2.

  2. Hourly Pod CPU Cost: Calculates the cost of a single CPU unit per hour per pod.

    • Instance Price Per Hour = The hourly price of the node. This data is taken from step 3.

    • CPU Count = Number of cores within the node

    • CPU Ratio = 88% by default

    • RAM (GiB) = Number of GiBs within the node

    • Memory Ratio = 12% by default

  3. Hourly Pod Memory Allocation: Hourly Pod Memory Allocation is used to determine how much of the node’s CPU was allocated. It is based on the greater value of the average hourly CPU usage or the average hourly CPU request. See the full explanation about parsing the metrics per pod in step 2.

    Note: For AKS cost calculation (Azure), the calculations are performed on a daily granularity, not an hourly granularity.

  4. Hourly Pod Memory Cost: Calculates the cost of a single Memory unit per hour per pod.

    • Instance Price Per Hour = Hourly price of the node. This data is taken from step 3.

    • CPU Count = Number of cores within the node

    • CPU Ratio = 88% by default

    • RAM (GiB) = Number of GiBs within the node

    • Memory Ratio = 12% by default

Example:

You have one node with 4 vCPUs and 12 GiB RAM.

  • The cloud bill shows $10.00 for this hour.

  • Two pods are running, and in both cases usage < request, so we use requests (from Step 2):

    • podA: 2 cores, 3 GiB

    • podB: 1 core, 5 GiB

Note: The “CPU count” and “RAM count” values are identical for both pods because they are derived from the node that hosts them (the node has 4 cores and 12 GiB). Since both pods run on the same node, each pod’s entry reflects the node’s total CPU and memory capacity rather than pod-specific usage.

Based on this setup, let’s break down the pod cost calculation into the variables below.

Variable
podA
podB

Hourly pod CPU allocation

2 cores

1 cores

Hourly pod Memory allocation

3 GiB

5 GiB

Ratio CPU:Memory

88:12

88:12

Calculating Hourly Pod CPU Cost (shared; same node)

(10/(4×0.88 + 12×0.12))×0.88 = 1.774$

(10/(4×0.88 + 12×0.12))×0.88 = 1.774$

Calculating Hourly Pod Memory Cost (shared; same node)

(10/(4×0.88 + 12×0.12))×0.12 = 0.242$

(10/(4×0.88 + 12×0.12))×0.12 = 0.242$

Calculating Hourly pod cost

(1.774×2 + 0.242×3) = 4.274$

(1.774×1 + 0.242×5) = 2.984$

Based on this breakdown, the node cost according to Finout (Recommended algorithm) is: 4.274$ + 2.984$ = 7.258$.

Proportionally, the Node idle cost is: 10$ − 7.258$ = 2.742$.

Compute Cost - Legacy Algorithm

The legacy algorithm uses a 50:50 CPU:Memory ratio for accounts created before November 2024, and haven’t been migrated to the refined algorithm yet. This balanced split was ideal for average workloads, but could result in inaccurate financial reporting when actual resource configurations differ. Hourly Pod Cost - This refers to the cost of the pod per hour, which is the total price without distinguishing between memory and CPU usage.

The CPU/Memory pricing of the legacy algorithm is calculated using the following formulas:

1. Hourly Pod CPU Allocation - Hourly pod CPU allocation is used to determine how much of the node’s CPU was allocated. It's based on the greater value of the average hourly CPU usage or the average hourly CPU request. See the full explanation about parsing the metrics per pod in step 2.

2. Hourly Pod CPU Cost - Calculate the CPU cost by applying the CPU allocation ratio to the node’s total cost, adjusted for the node’s active time. This calculation is based on the hourly pod CPU allocation derived in the previous formula.

Note: Uptime is calculated on an hourly basis. In vendor billing, node uptime is reported as a fraction of the hour (0–1), while some metric sources report seconds. Since billing values are limited to a range of 0–1 per hour, total costs aren’t derived by multiplying by total hours. Uptime is calculated separately for each hour, and the hourly pod costs are then summed to produce the daily total.

3. Hourly Pod Memory Allocation - Hourly pod memory allocation shows how much of the node’s memory was allocated. It is calculated as the greater value of the average hourly memory usage or the average hourly memory requests. See the full explanation about parsing the metrics per pod in step 2.

4. Hourly Pod Memory Cost - Calculates the Memory cost out of the node’s total cost, using the allocation ratio, considering the actual time the node was active and in use. This calculation is based on the hourly pod memory calculation derived in the previous formula.

Note: Uptime is calculated on an hourly basis. In vendor billing, node uptime is reported as a fraction of the hour (0–1), while some metric sources report seconds. Since billing values are limited to a range of 0–1 per hour, total costs aren’t derived by multiplying by total hours. Uptime is calculated separately for each hour, and the hourly pod costs are then summed to produce the daily total.

Example:

  • You have one node with 4 vCPUs and 12 GiB RAM.

  • The cloud bill shows $10.00 for this hour.

  • Two pods are running, and in both cases usage < request, so we use requests (from Step 2):

    • podA: requesting 2 CPUs and 3 GiB RAM, node uptime = 1 hour

    • podB: requesting 1 CPU and 5 GiB RAM, node uptime = 0.5 hour

    • Totals (this hour):

      • Cores count = 3

      • GiB count = 8

Based on this setup, let’s break down the pod cost calculation into the variables below:

Variable
podA
podB

Hourly pod CPU allocation

2 cores

1 cores

Hourly pod Memory allocation

3 GiB

5 GiB

Ratio CPU:Memory

50:50

50:50

Node Uptime (hourly fraction)

1

0.5

Calculating Hourly Pod CPU Cost

(Node Price / # Cores) x [Hourly] Pod CPU Allocation x Node Uptime : (10 / 3) x 2 x 1 = 6.66$

(Node Price / # Cores) x [Hourly] Pod CPU Allocation x Node Uptime : (10 / 3) x 1 x 0.5 = 1.66$

Calculating Hourly Pod GiB Cost

(Node Price / # GiB) x [Hourly] Pod GiB Allocation x Node Uptime : (10 / 8) x 3 x 1 = 3.75$

(Node Price / # GiB) x [Hourly] Pod GiB Allocation x Node Uptime : (10 / 8) x 5 x 0.5 = 3.125$

Calculating hourly pod cost (50:50)

6.660.5 + 3.750.5 = 5.205$

1.660.5 + 3.1250.5 = 2.392$

Based on this breakdown, the node cost according to Finout (Legacy algorithm) is: 5.205$ + 2.392$ = 7.6$. Proportionally, the Node idle cost is: 10$ − 7.6$ = 2.4$.

Network cost

Finout determines each node’s hourly data transfer cost using cloud provider data. It then allocates this cost to individual pods by analyzing their incoming and outgoing network traffic. Each pod’s share of the total node network cost is calculated according to its usage of the network metrics.

Step 5: Calculate Node-Level Idle

For each node and hour, Node Idle is the unallocated portion of the node’s price after pod costs are attributed according to Finout’s calculation in Step 4:

Node Idle (per hour) = Node Price (billing, Step 3) − Σ (pod costs on that node for the same hour, Step 4)

Why does this happen?

Idle capacity on a node is often associated with oversized instances or uneven packing. Kubernetes schedules pods onto available space; in busy, mixed workloads it’s tempting to use larger nodes that can host many pods. When demand drops, those large nodes can sit partially empty. Using smaller instance types (or tuning autoscaling) can reduce this idle. Conversely, nodes that are too small may also end up underused if they can’t efficiently host multiple workloads.

Where to see and how to allocate

Node-level idle appears in Finout under the Idle Namespace dimension. Teams often allocate it differently from overhead (platform essentials) to encourage efficiency. Use Virtual Tags to distribute Node Idle across the teams/applications of your choice.

What to do next?

Use CostGuard to identify and optimize Workload Idle (also known as waste), which occurs when resource requests exceed actual usage. CostGuard’s Idle/Rightsizing scans help you right-size CPU/Memory requests and reduce waste.

Last updated

Was this helpful?