Cost
The Cost page, under FinOps, shows what your clusters cost and where the money goes: to which namespaces, workloads, teams and node pools, how much pays for capacity nothing is using, and what you spend moving data between zones, regions and the internet.
Everything is worked out inside your environment from what Ultraviolet already observes. No billing access or cloud credentials are needed, and it works fully air-gapped. If you bring in your cloud bill (optional — see Cloud bill), it adds the invoice, everything outside the cluster and your commitments, and prices nodes at what you were actually charged.
How cost is worked out
Section titled “How cost is worked out”- Each node is priced from public on-demand list prices for its cloud, region and instance type, at the spot price when the node is spot or preemptible. Nodes that run on-premises, or whose type isn’t recognised, are priced per vCPU-hour and per GiB-hour.
- Each workload is charged for the CPU and memory it reserves or uses — whichever is larger — at the price of the node it runs on. A replica on a spot node costs less than the same replica on an on-demand node.
- Whatever is left over is idle. Capacity you pay for that no workload requested or used shows as Idle capacity rather than being spread invisibly across everyone. It’s usually the largest single saving.
- Network transfer is priced per workload from where its traffic goes: internet, another region, or another zone in the same region (billed in both directions). Traffic within a zone is free.
- Storage — each persistent volume is priced by its size and disk type (standard, balanced, SSD…) and charged to the workload whose pods mount it. A volume nothing mounts shows as Unattached volumes.
- Load balancers — each Service of type LoadBalancer is priced at its cloud’s hourly rate and charged to its namespace (and its own labels).
These are estimates. Set your real prices under Pricing (below) and they get close; reserved instances and savings plans can be entered as your actual price per instance type. With your cloud bill imported, nodes it covers are priced at what it charged instead.
The page
Section titled “The page”- Headline numbers — total cost for the time range, the monthly run-rate at that pace, idle capacity (and its share of compute), and network transfer.
- Daily cost — a stacked chart of what workloads used, what sat idle, and network transfer, day by day.
- Breakdown — group by namespace, workload, any label (for
example
teamorcost-centeron your Deployments), node pool, node, cluster or site. Each row shows compute, network and total cost, its share, and efficiency: usage as a share of requests over the range.- Low efficiency means paying for reserved capacity that isn’t used — a candidate for smaller requests.
- Above 100% means a workload uses more than it requests, and can be squeezed when its node gets busy.
- Network transfer — cost by destination, and the workloads spending the most on it.
- Nodes — every node with its instance type, region, spot or on-demand, hourly price and where that price came from.
Cost history is kept for 400 days, independent of how long you keep traces, logs and metrics, so month-over-month comparisons survive your telemetry retention. It starts when you install or upgrade to a version with the Cost page: compute from the previous 30 days of metrics where available, network transfer from the previous day.
Unit cost
Section titled “Unit cost”For each workload that serves requests, the breakdown shows its cost per 1,000 requests — its compute, network, storage and load balancer cost over the requests it served (health checks excluded). It answers “what does serving this traffic cost?”, and rises when a service gets less efficient even if its total cost doesn’t.
Ownership
Section titled “Ownership”Every cost should belong to a team. The Ownership card shows how much
workload spend carries an owner label (team by default — change it on the
card) and lists the largest spend with none, so you know which Deployments to
label. Label your workloads and the label grouping, budgets and reports follow.
Reports
Section titled “Reports”The Reports tab is showback and chargeback: a month’s cost per owner — by label (a team, a cost-center) or by namespace — with compute, network, storage, load balancers and total. Choose how idle capacity is treated:
- Shared proportionally — idle capacity and unattached volumes are spread across owners by their cost, so the rows add up to the whole bill (for chargeback);
- Shown separately — idle stays its own line (for showback, and for seeing what’s wasted).
CSV downloads the report for a spreadsheet or finance system. Editors can Schedule it: early each month, last month’s report goes to your notification channels (email or chat).
Savings
Section titled “Savings”The Savings tab lists what you could change to spend less, each with an estimated monthly saving and the evidence behind it. Recommendations are recomputed every hour from the last seven days — a full weekly cycle — and need at least a day of data before they appear.
| Recommendation | What it means |
|---|---|
| Rightsize CPU / memory | A workload requests far more than it uses. The suggestion keeps headroom: CPU at 30% above its 95th-percentile hour (and above its busiest hour), memory at 20% above its peak. The saving is realised once the node pool shrinks to match. |
| Consolidate nodes | A node pool’s busiest hour would fit on fewer nodes, packed to 80% of what they can schedule, after allowing for DaemonSets that run on every node. |
| Use spot | A stateless Deployment with several replicas runs on on-demand nodes; spot capacity typically costs 65–75% less. |
| Network | A workload pays to send traffic across zones or regions, with how to keep it local. |
| Unused | Deployed and paid for, but in seven days it served no requests other than health checks, made none, and moved under 20 MB a day over the network. Check for work it does that Ultraviolet can’t see before removing it. |
| Unused volume | A persistent volume no pod has mounted all week — its claim was deleted (the disk is kept, and billed, until it’s removed) or nothing uses the claim. |
| Commitment | From your cloud bill: on-demand compute has held steady enough that a 1-year savings plan or committed use discount would almost always be fully used. Sized at the level spend stayed above on 9 days in 10 over the last 30 days, with the saving at a typical discount — check the exact rate for your instance families before buying. |
| Risk | Not a saving: a workload uses well beyond what it requests (and is throttled or evicted first when its node is busy), or requests nothing at all. |
Editors can snooze a recommendation for 30 days or dismiss it; both are recorded in the audit log, and Show dismissed and snoozed brings them back into view. Savings can overlap — rightsizing frees capacity that consolidation then removes — so the total is an upper bound.
Budgets
Section titled “Budgets”A budget is a monthly limit on all spend, a namespace, or a label
value — for example team=payments on your Deployments. Each one shows what
has been spent this month and a forecast for month-end, projected at the
last seven days’ daily rate.
Editors choose when a budget alerts: when spend reaches given percentages (80% and 100% by default), and — optionally — as soon as the month-end forecast goes over, so there is time to act. Each threshold alerts once a month. Alerts go to your notification channels, all of them or the ones you pick.
An “all spend” budget counts every node’s full cost, idle capacity included, plus network transfer — what your cloud bills. A namespace or label budget counts its workloads’ share.
Cost anomaly alerts
Section titled “Cost anomaly alerts”Every hour, Ultraviolet compares each namespace’s and workload’s cost over the last 24 hours with its usual level: the same weekday over the past few weeks, or the previous week when there isn’t that much history yet. When it’s 50% higher and at least $10 more (both adjustable under Alerts → Settings), it alerts — once, until the cost settles back down — and says what changed:
- more CPU requested (more replicas, or larger requests);
- more CPU used;
- each core costing more (moved to a larger node type, or from spot to on-demand);
- more network transfer;
- and, for a namespace, which workloads the increase came from.
Namespace shop cost $50.00 in the last 24 hours, against a usual $20.00 (the same weekday over the last 4 weeks) — 150% more. What changed: CPU requested rose 2.5× — more replicas or larger requests; mostly from api +$30.00.
When a namespace alerts, its workloads don’t alert separately, so one cause sends one notification. The Alerts tab keeps the history of anomalies and budget alerts.
Cloud bill
Section titled “Cloud bill”The Cloud bill tab reads your bill from AWS, Google Cloud or Azure, in the FOCUS format (the FinOps Open Cost and Usage Specification) all three export. It shows, for each billing month:
- Invoice — the total, with usage, tax, credits and purchases.
- Kubernetes vs everything else — the machines that are your nodes, other resources your clusters own (disks, load balancers), and everything outside the cluster: databases, object storage, NAT and the rest.
- Outside the cluster, by owner — that spend grouped by an owner tag (such
as
team), with the share that carries one and the largest untagged resources. - Cluster estimate vs the bill — the list-price estimate for your nodes next to what the bill charged for the same machines, per node pool, over the days the bill covers. Turn on Price nodes from the bill and the Cost page uses the billed rates: nodes the bill names are priced at their charge, and newer nodes of the same instance type at the same ratio. Costs are amortised — savings plans, reserved instances and committed use discounts are spread over the usage they cover.
- Commitments — coverage (the share of compute on commitments), utilization (how much of what you committed to was used, and what went unused), and a recommended new commitment when steady on-demand spend justifies one.
The bill never leaves your environment. Bring it in one of two ways:
Pull it from your account. An admin chooses Source and points it at the export, then it syncs every 6 hours, re-reading a month whenever the cloud restates it.
| Cloud | Set up the export | Source |
|---|---|---|
| AWS | In Billing and Cost Management → Data Exports, create a FOCUS 1.0 export to an S3 bucket, with CSV files. | Bucket: s3://bucket?region=…, folder: the export’s prefix |
| Azure | In Cost Management → Exports, create a FOCUS cost export to a storage container, CSV. | Bucket: azblob://container, folder: the export’s directory |
| Google Cloud | Enable the detailed billing export to BigQuery and create the FOCUS view over it. | BigQuery: project.dataset.view |
Ultraviolet reads the export with its own cloud identity — workload identity on
EKS (IRSA), GKE or AKS, granted read-only access to the bucket or the BigQuery
view — or with keys your operator provides in a Kubernetes Secret
(queryApi.cloudBill.existingSecret). Reading through BigQuery runs queries
billed to the query project.
Upload it. For an air-gapped installation, download the month’s FOCUS export
(CSV, or .csv.gz) and choose Upload. Uploading a month again replaces it.
Imports lists every import and sync, with any errors.
Pricing
Section titled “Pricing”Editors can open Pricing on the Cost page to set:
| Setting | What it does |
|---|---|
| Negotiated discount | A percentage off list price for compute and network transfer, such as an enterprise agreement discount. |
| On-prem and unrecognised nodes | Your own price per vCPU-hour and per GiB-hour, for nodes that aren’t from a recognised cloud instance type. |
| Instance type prices | Your actual hourly price for an instance type — for example under a reserved instance or savings plan. Used as entered, without the discount. |
Changes apply to the whole range on the next refresh and are recorded in the audit log.