Cost and Resource Metrics
AstroPulse answers two questions about everything running on your clusters:
- What is it using? Live CPU, memory, and network per application.
- What is it costing? Reserved and used resources, priced, per cluster, namespace, and application.
Both require a connected, compatible Astro agent and work on provisioned or registered clusters across supported cloud providers and on-premises. Agent installation and capabilities are managed through AstroPulse; BYO Kubernetes registration installs the agent by default.
Requests decide who holds paid capacity
Your cloud provider bills for nodes and related infrastructure, not Kubernetes requests. Requests still matter because the scheduler uses them to determine whether another Pod fits, even when observed usage is low.
A Pod that requests four cores and then idles holds four cores of schedulable capacity. That headroom may be intentional: teams use requests to preserve schedulable capacity for bursts, startup behavior, and reliability. When a request is larger than the workload needs for those conditions, it can prevent node consolidation or consume room another workload could use.
Every cost view shows allocated next to used. The comparison identifies workloads to investigate; it does not calculate a safe replacement request. Check peak windows, autoscaling behavior, throttling or eviction signals, and SLOs before changing resources.
How it works
The Astro agent running in the cluster does the measuring.
Resource metrics need no separate collector once the agent is connected. The agent reads what Kubernetes already knows about the workloads the platform deployed, and reports a small summary — time-averaged CPU, memory working set, and network throughput per application. It samples continuously and reports periodically, so the console shows a live picture within a minute or two.
Cost requires the Cost Visibility add-on, which installs the metering stack on the cluster. Once installed, the agent closes one window per hour, prices it, and reports the finished result.
Three properties follow from doing the work in the cluster:
- Attribution happens where the truth is. The agent resolves which application a workload belongs to from the cluster's own records, so the answer is the same one Kubernetes would give.
- Only summaries leave. The platform receives per-application totals, not your pod names, container images, logs, or environment.
- A disconnected cluster loses nothing permanently. The agent holds finished cost windows until it can deliver them, then catches up.
Two different clocks
Metrics and cost deliberately run on different cadences, because they answer different questions.
| Resource metrics | Cost | |
|---|---|---|
| Question | What is it doing right now? | What did it cost? |
| Granularity | Minutes | One closed hour |
| Freshness | Within a minute or two | After the hour completes |
| Needs an add-on | No | Yes — Cost Visibility |
| History kept | About 24 hours | 1 day on Developer, 395 days on Enterprise |
Cost waits for the hour to finish on purpose. A partial hour priced as though it were whole is not a cheaper hour, it is a wrong number.
How long history is kept
The two are kept for different lengths of time, because they cost different amounts to keep.
Resource metrics are a live working set. They answer what a workload is doing now, so they are held for about a day and then trimmed. This is the same on every plan.
Cost history is durable, and how much you keep depends on your plan.
| Plan | Cost history |
|---|---|
| Developer | 1 day |
| Enterprise | 395 days |
One day on Developer keeps the current-day view working. 395 days is thirteen months, which is what year-over-year comparison actually needs — the same month last year, plus a margin.
Enterprise organizations start at 395 days and it is adjustable: retention is a per-organization setting, so a contractual or regulatory requirement can be met without changing anyone else's.
Retention removes history that has aged out. It never changes what is measured or which views you get — every plan has the full feature, and the difference is how far back you can look.
Cost history belongs to the cluster that produced it. When the cluster record is removed, its entire cost history goes with it — every window, on every plan, straight away. This is not governed by the retention period above: an organization keeping 395 days still loses all 395 days for that cluster at the moment it is removed.
Both of these remove the cluster record, so both remove its cost history:
| Command | Cluster type | Cost history |
|---|---|---|
astroctl infra k8s delete | Provisioned | Deleted |
astroctl infra k8s unregister | Registered | Deleted |
This is worth stating plainly for unregister, because it is otherwise the
gentler of the two: it leaves your applications running and does not touch the
underlying cluster. It still ends that cluster's cost history.
The history is keyed to the cluster's internal identity rather than its name, so recreating or re-registering a cluster with the same name does not bring it back. There is no undo.
Export anything you need to keep first. Every cost command takes -o json:
astroctl infra k8s cost allocation my-cluster \
--group-by application --window 30d -o json > my-cluster-cost.json
Resource metrics need no equivalent warning: they are a live working set that ages out within about a day whatever happens to the cluster.
Reading the numbers
Used CPU is an average, not a recommended request. A workload may need substantial headroom for bursts even when its average utilization is low. Use the gap to find candidates for review, then validate peak behavior and reliability requirements before changing requests.
Utilization can exceed 100%, and it is not capped. A workload consuming more than it reserved is reported above 100% and flagged. Capping it at 100 would hide use above the scheduled baseline. Whether that causes throttling or eviction depends on limits, QoS, priority, and node pressure.
No requests set is not 0% and not 100%. A workload with no resource requests is reported as having none set, because a ratio against zero is not a measurement. It has no reserved share for that resource; eviction behavior depends on its complete requests and limits, usage, priority, and node pressure.
CPU and memory are reported separately. They are sized independently, and a single blended score hides which one is wrong.
A missing measurement is never zero. This is the rule the whole feature is built around. An hour that produced no report is missing. An hour the agent could not recover is a gap. A window nobody measured is absent from the chart rather than plotted at zero, because a flat zero on a CPU graph reads as an outage rather than as silence. Every total states the coverage behind it:
Totals include 22 of 24 expected hours. Missing and gap hours are not counted as $0.
Check coverage before you act on a number. A cheap-looking day may be a partly-measured day.
Where to see it
- Console
- CLI
- Ask Nova
Every application, cluster, and add-on has Metrics and Cost tabs.
- Application → Metrics: CPU, memory, and network for that application.
- Application → Cost: its spend, utilization, and share of the cluster.
- Cluster → Metrics: every application on the cluster, ranked. An application that reported nothing in the window is omitted rather than listed at zero.
- Cluster → Cost: cluster spend, and allocation grouped by namespace or application.
# One application
astroctl application metrics checkout --window 1h
astroctl application cost checkout --window 24h
# A whole cluster
astroctl infra k8s metrics summary my-cluster --window 1h
astroctl infra k8s metrics allocation my-cluster --window 1h
astroctl infra k8s cost allocation my-cluster --group-by application
# Largest request-to-average gaps first — review burst headroom before changing
astroctl infra k8s cost allocation my-cluster \
--group-by namespace --sort-by efficiency --sort-order asc
Ask in plain language — Nova reads the same data:
Which workloads on my-cluster are reserving far more CPU than they use?
What did checkout cost yesterday, and how much of the window did we actually measure?
Add-ons are measured too
Add-ons run on your cluster and consume real resources, so they report cost and metrics like any other application. Open an add-on from the cluster's Add-ons tab and its Metrics and Cost tabs are there.
This is deliberate. A cluster total that quietly omitted the platform's own add-ons would not reconcile against your bill, and you would have no way to see what the platform costs you.
Add-ons stay out of your Applications list — that list is yours — and are addressed through the cluster they belong to:
astroctl infra k8s addons metrics my-cluster cost-visibility --window 1h
astroctl infra k8s addons cost my-cluster cost-visibility --window 24h
Spend that belongs to no namespace
Some of what a cluster costs is not attributable to anything running on it:
| What it is | |
|---|---|
| Idle capacity | Capacity the cluster is paying for that no workload has requested. A node with 8 cores running Pods that request 3 leaves 5 cores idle — provisioned, billed, and doing nothing. |
| Cluster overhead | The cost of running the cluster itself rather than anything on it, such as a managed control plane. |
These are reported separately from the breakdown, under unattributed, because
neither is a namespace, an application, or a node group — grouping cannot place
them. They are reported rather than dropped because they are real charges: a
breakdown without them adds up to less than your bill, with nothing to explain
the difference.
Idle capacity is usually the most actionable number here. Requests decide what you pay for, so persistent idle means the cluster is larger than the requests on it — either the workloads ask for more than they use, or there are fewer of them than the nodes were sized for.
# the breakdown, then what no namespace owns
astroctl infra k8s cost allocation my-cluster --group-by namespace -o json
Pricing and what is not included
Measuring quantities needs no configuration. Pricing them does, and it is one explicit step: supply a price sheet with the add-on — your rates for a CPU core-hour, a GB-hour of memory and storage, and a GPU-hour.
This is the same on every cluster, on any cloud or on-premises, because it depends on nothing outside the cluster. Rates you supply are usually the ones worth having: committed-use, negotiated, or internal chargeback rates all produce totals closer to your invoice than a public rate card would.
Alternatively, the add-on can read a billing export inside your cluster and attribute the provider's invoiced rates. Raw billing rows and credentials stay in your environment; the platform receives only aggregated workload cost summaries. See Cost Visibility configuration for the supported providers and setup.
A cluster without either source is unpriced: quantities are still measured in full — allocation, usage, and utilization all work normally, enough to find large request-to-average gaps without pricing anything — and only the currency figures are absent.
unpriced is a deliberate outcome rather than a failure, and it follows the
same rule as the rest of the feature: a number nobody's rates produced is worse
than no number. Every priced figure is labelled with the rates behind it, so it
is always visible where a total came from.
Figures derived from a provider export are labelled cloud-bill. Full
platform-side reconciliation against an invoice is a separate provenance level
and is not part of this release.
Requirements
| Requirement | |
|---|---|
| Supported cluster | Any supported provisioned or registered cluster with a connected, compatible Astro agent. |
| Resource metrics | A connected Astro agent; no separate metrics collector is required. |
| Cost | A connected, compatible Astro agent and the Cost Visibility add-on. If prompted, update the agent before installing the add-on. |
| Currency figures | A price sheet or supported cloud billing export on the add-on. Without either, quantities are measured and cost reads unpriced. |
If an application reports no metrics, the usual cause is that it was deployed outside AstroPulse: the platform measures what it deployed, and does not claim ownership of workloads it did not.