← FinOpsAid blog

Are our self-hosted runners actually cheaper? Reading the Runners page — FinOpsAid blog

Are our self-hosted runners actually cheaper? Reading the Runners page

Modeled monthly cost, peak vs average utilization, the online/busy/offline inventory and GitHub-hosted larger runners — what each figure means and why 100% utilization is not the goal.

Runners is the page where FinOpsAid is least able to tell you the truth on its own, and it says so. GitHub does not bill you for a self-hosted runner — your cloud provider or your data centre does. So every dollar on this page is modeled from infra rates you supply, and if you haven't supplied them, the modelled figures are only as good as the defaults.

What the page can tell you exactly is utilization, and that's the number that decides whether self-hosting was a good idea.

The KPI row

Tile What it counts Direction
Modeled Cost / mo Sum of every runner's modeled monthly cost. Footnote: "from your infra rates". Worse. Modeled, always.
Total Runners Registered runners in the fleet. Neutral.
Online Runners currently reachable. Higher relative to total is better — offline runners are usually forgotten VMs.
Peak Utilization The highest utilization percentage observed in the window. See below — neither direction is simply good.
Avg Utilization Mean utilization across the window. Higher is better up to a point, then it isn't.

Utilization: the one number with two failure modes

Reading runner utilization in three bands Below roughly thirty percent average utilization the fleet is oversized and money is being spent on idle capacity. Between roughly thirty and seventy percent the fleet is appropriately sized with headroom for peaks. Above roughly eighty-five percent, and especially where peak utilization is pinned at one hundred percent, jobs are queueing and the hidden cost is developer waiting time rather than infrastructure spend. AVG UTILIZATION — THE COST IS ON BOTH ENDS UNDER ~30% Oversized. Paying for idle. ~30–70% Sized right, with headroom for peaks. OVER ~85% Queueing. Devs are waiting. Peak and Avg tell different stories, and you need both. Low avg + peak at 100% = a bursty workload. Don’t shrink the fleet; smooth the bursts or add autoscaling. Low avg + low peak = genuinely oversized. Shrink it. High avg + peak at 100% = under-provisioned. The cost is invisible: it lands in cycle time, not the bill. 100% utilization is not efficiency. A queue at 100% means every job waits for the one in front.
This is the only page in FinOpsAid where a higher percentage is not obviously better. Peak and average must be read together — one number alone can't distinguish "bursty" from "undersized".

Utilization over time

A daily area chart of utilization percentage across the fleet, not money. Combined with the Actions minutes chart on the GitHub Actions page, it answers whether spikes in demand are being absorbed or are queueing.

A flat line near zero across a whole window, with the fleet still online, is the clearest possible finding: you're paying a standing monthly charge for machines nobody is using.

Runner inventory

Sorted by modeled monthly cost descending.

Column Meaning Direction
Name Runner name, linking to GitHub's runner settings.
OS Operating system.
Status Green online or grey (offline). Online is expected; a long-term offline runner is a cleanup item.
Busy yes / no at snapshot time. A point-in-time flag, not a rate — use the utilization chart for the rate.
Modeled Cost / mo Our estimate from your infra rates. Lower is better.

The card subtitle repeats the caveat: "Self-hosted runner cost is modeled from customer-supplied infra rates." If those rates are stale — an instance type changed, a reserved-instance commitment landed, a region moved — every dollar in this table is stale with them. Rates are a Settings concern, and reviewing them is a quarterly job.

GitHub-hosted runners

A separate card at the bottom, present only when the org uses GitHub-hosted larger runners. These are a different animal: GitHub bills them per minute by size, but does not publish a dollar rate per runner, so the page models cost from vCPU count.

Column Meaning
Runner / Platform / Size Identity and machine class.
vCPU and Memory (GB) The provisioned shape.
Status Green when ready, amber otherwise.
Modeled $/hr Estimated hourly cost from vCPU.

The card header carries the fleet total: modeled dollars per hour and total vCPU across all hosted runners. That vCPU total is the useful number — it's the size of the commitment, expressed in units GitHub actually reports.

Self-hosted versus hosted: what this page can settle

It can settle the utilization half of the argument, which is the half most teams get wrong. Self-hosting wins when a fleet is well utilised, because you're paying for capacity you use. It loses badly when utilization is low, because GitHub-hosted runners bill only for minutes consumed while your own machines bill for existing.

What this page cannot settle is the operational cost — the engineer time spent patching, scaling and debugging the fleet. That never appears on any bill, and it is routinely the larger number. There's a fuller treatment in are self-hosted GitHub runners cheaper.

What people get wrong on this page

The 60-second read

Frequently asked questions

Is 100% runner utilization a good thing?

No. Utilization pinned near 100% means jobs are queueing and developers are waiting — a cost that never appears on any bill. Roughly 30 to 70% average utilization is a healthy band with headroom for peaks. Below about 30% the fleet is oversized.

Why is self-hosted runner cost shown as modeled?

GitHub never bills you for a self-hosted runner; your cloud provider or data centre does. FinOpsAid estimates the cost from infrastructure rates you supply, so the figure is exactly as accurate as those rates. Review them when instance types, regions or commitments change.

Are self-hosted runners cheaper than GitHub-hosted ones?

Only when utilization is high. Self-hosted machines bill for existing, so idle capacity is pure loss, whereas GitHub-hosted runners bill only for minutes consumed. This page settles the utilization half of the question; it cannot measure the engineering time spent patching and scaling the fleet, which is often the larger cost.

Want to size your own fleet with real numbers? Connect your GitHub org — read-only and free during beta — or explore the demo first. Next: how to read the Codespaces page.