← FinOpsAid blog

Where are our CI minutes going? A guide to reading the GitHub Actions page — FinOpsAid blog

Where are our CI minutes going? A guide to reading the GitHub Actions page

Modeled spend, total runs, success rate, average duration, runner health and cache storage — every card on the FinOpsAid Actions page, and which numbers reconcile to a bill.

Actions is the page where a usage signal and a dollar figure sit closest together, and where the gap between them matters most. GitHub bills Actions by the minute against an included allowance; what it reports to you is minutes, and what this page shows you as dollars is those minutes with a rate applied. The tile says "Modeled Spend" precisely so nobody forgets.

The conventions used below come from the grammar behind every number.

The KPI row

Tile What it counts Direction
Modeled Spend Actions cost derived by applying a rate to billable minutes. Not a billed figure. Worse.
Total Runs Workflow runs in scope. Neutral — runs aren't the cost driver; minutes are.
Success Rate Share of runs that succeeded, to one decimal place. Higher is better. One of the "up is good" tiles.
Avg Duration Mean run duration in minutes. Lower is better — usually. See the caveat.
Runners Total registered runners, with the online count as a footnote. Neutral. Detail on Runners.

Avg Duration deserves a caveat. It's a mean across every workflow, so a nightly job that runs for two hours drags it up and tells you nothing about the pull-request feedback loop that developers actually feel. If the number looks bad, go to the per-workflow table before you conclude anything — the mean is a starting point, not a diagnosis.

Success Rate is a cost metric here, not just a quality one. A failed run bills the minutes it consumed before it failed. At a 90% success rate, roughly a tenth of your CI minutes bought nothing. That is the most direct link between reliability and spend anywhere in the product.

Failed runs bill exactly like successful ones A bar representing total billable minutes is split into a large teal portion for successful runs and a smaller amber portion for failed runs. The amber portion is billed at the same rate but produces no artefact, no deployment and no green check, making it the clearest waste signal on the page. SUCCESS RATE, TRANSLATED INTO MONEY Total billable minutes this period SUCCEEDED — 90% 10% The amber slice is billed at the same per-minute rate and produced nothing. A 90% success rate on a $40,000 CI bill is roughly $4,000 spent on runs that failed. Flaky tests are not only a developer-experience problem. They are a recurring line item. The Failed column on the Repositories page tells you which repos own that slice.
This is the arithmetic that makes reliability work fundable. The exact split is approximate — failed runs are usually shorter than successful ones — but the direction is right and the argument survives scrutiny.

Actions minutes over time

A daily bar chart of billable runner minutes, scoped by the Period filter. Minutes, not dollars — this is the honest series, and it's the one to screenshot when someone asks what drove the bill.

Look for shape, not level. A weekday sawtooth with quiet weekends is a healthy pattern. A flat line that never dips is scheduled work running regardless of whether anyone is developing — the cron problem covered in Actions costs hiding in plain sight.

Top Workflows by Minutes

A table of the eight heaviest workflows: Workflow, Runs, Minutes — sorted by minutes descending, each name linking to a per-workflow detail page.

This is where the Avg Duration tile becomes actionable. High minutes with low runs means a small number of very long jobs; high runs with moderate minutes means something fires constantly. Those are different problems: the first is a caching or parallelism question, the second is a trigger-configuration question.

The workflow detail page shows Modeled Cost, Runs, Success (with the failed count beside it, and marked as a higher-is-better metric), Minutes, a daily minutes chart, and a recent-runs table listing run ID, repository, conclusion and duration. That runs table is where you confirm a suspicion — a workflow whose recent conclusions alternate between success and failure is flaky, not broken.

Runner health

Four counters and a cost list.

Counter Meaning
Online Registered and reachable.
Busy Currently executing a job.
Idle Online but not executing.
Offline Registered but unreachable.

Underneath, a ranked list of the six most expensive runners by modeled monthly cost, labelled with name and OS.

Read these as a set. Persistent Idle across many runners means you're paying for capacity that never gets used — the fleet is oversized. Persistent Busy across all of them means jobs are queueing, and the cost you can't see is developers waiting. Offline runners are the awkward case: they consume no compute, but if they're VMs someone forgot to deprovision, the infrastructure bill continues regardless of what GitHub thinks of them.

Self-hosted runner cost is modeled from infra rates you supply, so its accuracy is exactly as good as those rates. Full detail is on the Runners page.

Actions cache storage

The last card, and one that only appears when there's data. It shows billed cache storage — the org total in GB and the number of caches, then a per-repository table of cache count and size.

This card is billed, not modeled. Cache storage is a real line item, and it accumulates in a way that surprises people: caches are created eagerly by workflows and evicted lazily, so a repository that ran an aggressive caching strategy for one release can hold gigabytes for a long time afterwards. Archived repositories still hold cache.

The reason it lives on the Actions page rather than Storage is that its cause is here — a workflow configuration created it, and a workflow configuration change is what fixes it.

What people get wrong on this page

The 60-second read

Frequently asked questions

Is the GitHub Actions spend figure a billed amount?

No, it is modeled — billable minutes multiplied by a rate, which is why the tile reads Modeled Spend. The minutes themselves are real and reported by GitHub. Use minutes when you need a figure that reconciles, and the dollar value for ranking and rough sizing.

How much does a low CI success rate actually cost?

Multiply your failure share by your Actions spend. A 90% success rate on a $40,000 CI bill means roughly $4,000 went on runs that produced nothing, because failed runs bill the minutes they consumed. That arithmetic is what makes reliability work fundable.

Why is Actions cache storage on the Actions page rather than Storage?

Because its cause lives here. Cache storage is billed, accumulates silently as workflows create entries eagerly and evict them lazily, and is fixed by changing a workflow's caching strategy. Putting it beside the workflows that created it puts it in front of the person who can act.

Want to see your own CI economics? Connect your GitHub org — read-only and free during beta — or explore the demo first. Next: how to read the Runners page.