Actions cost optimization

Ten workflows are the bill. Find them before you tune anything.

Short answer

GitHub Actions cost optimization starts with concentration, not technique: in most organizations a handful of workflows produce the majority of billed minutes. Rank workflows by cost, then apply four levers to the top of that list — trigger discipline, caching, runner sizing, and concurrency cancellation. Broad, org-wide tuning campaigns almost always cost more effort than they save.

Rank before you tune

CI cost is concentrated. A small number of workflows — usually an integration suite, a matrix build that grew a dimension nobody removed, and a nightly job whose purpose has been forgotten — account for most of the minutes. The long tail is genuinely cheap.

This changes what good optimisation looks like. A campaign asking every team to trim their pipelines burns weeks of engineering time for a few percent. Fixing the top ten workflows is a fortnight's work and moves the actual bill. Get the ranking first, in cost rather than minutes, and the work plans itself.

The four levers that matter

Trigger discipline
Path filters, branch filters, and not running the full suite on every draft push. The cheapest minute is one that never starts. This is usually the single biggest win on a mature repository.
Caching and reuse
Dependency caches, build caches, and not rebuilding what a previous job already built. Compounding: it shortens every subsequent run, not just the next one.
Runner sizing
Larger runners bill at a higher per-minute rate but can finish disproportionately faster — sometimes cheaper overall, often not. It is an empirical question per workflow, not a policy.
Concurrency and cancellation
Cancelling superseded runs when someone pushes three times in ten minutes. Pure waste elimination with no trade-off at all.

Artifacts and retention are a different bill

Actions produces two costs and people optimise only one. Minutes are the compute. Artifacts, logs and caches are storage, billed by volume over time, and they accumulate silently because nothing prompts you to delete them.

A workflow that uploads a large artifact on every run, with a long retention window, can quietly cost more in storage than it does in compute. Retention policy is a one-line change per workflow and it is the most commonly skipped optimisation in Actions.

Self-hosted runners are not automatically cheaper

Moving to self-hosted runners moves the cost, it does not remove it. The minutes stop appearing on your GitHub invoice and start appearing on your cloud bill — plus the maintenance, the security surface, and the idle capacity you now pay for whether or not anything is queued.

Idle time is the part that surprises people. A GitHub-hosted runner costs nothing between jobs. A self-hosted fleet sized for peak costs the same at 3am as at 3pm unless you have built autoscaling. Any comparison that ignores idle cost will conclude self-hosted is cheaper, and it will frequently be wrong.

Because that cost lands on infrastructure you own, FinOpsAid models it from your own rates and labels the result an estimate — it is not a figure GitHub bills you, and presenting it as one would be exactly the conflation we refuse to make.

Measure per-merge, not per-month

Total CI spend rises when engineering does more work, which makes it a bad optimisation target. Cost per merged pull request holds still when volume changes and moves when efficiency does. A month where total spend rose and cost per merge fell is a successful month, and only one of those two numbers will tell you so.

FAQ

Frequently asked questions

How do I reduce GitHub Actions costs?

Rank workflows by billed cost and fix the top ten. Apply trigger discipline so full suites do not run on every push, add dependency and build caching, right-size runners empirically per workflow, and cancel superseded concurrent runs. Org-wide tuning campaigns cost more engineering time than they recover.

Are larger GitHub-hosted runners cheaper?

Sometimes. A larger runner bills at a higher per-minute rate but can complete disproportionately faster, so total cost can fall. It depends entirely on whether the workload parallelises. Test it per workflow and compare total billed cost per run — it is an empirical question, not a policy you can set globally.

Do GitHub Actions artifacts cost money?

Yes. Artifacts, logs and caches are billed as storage by volume over time, separately from the minutes that produced them. A workflow uploading large artifacts on every run with a long retention window can cost more in storage than compute. Shortening retention is a one-line change and is the most commonly skipped Actions optimisation.

Are self-hosted runners cheaper than GitHub-hosted?

Only if you account for idle capacity and maintenance. Self-hosted moves the cost from your GitHub invoice to your cloud bill, and a fleet sized for peak costs the same overnight as at midday unless it autoscales. Comparisons that count only per-minute rates systematically favour self-hosted and are frequently wrong.

Try it

See these numbers for your own org

Connect your organization read-only and FinOpsAid meters it nightly — seats, credits, minutes, Codespaces and storage, attributed to teams and reconciled against your billing API. Every modeled figure is labelled an estimate, with the date it was computed.