GitHub Actions Billing, Explained: Minutes, Multipliers, and What Actually Gets Charged
How GitHub Actions billing works in 2026: per-job minute rounding, OS multipliers, free minutes by plan, failed and cancelled runs, who pays, and the January price cuts.
GitHub Actions bills for the time jobs spend executing on GitHub-hosted runners in private repositories. Each job's duration is rounded up to the next whole minute, multiplied by a per-minute rate that depends on the runner's operating system and size — as of 2026-07-28, $0.006 per minute for a standard 2-core Linux runner, $0.010 for Windows, and $0.062 for macOS, per GitHub's billing documentation — and charged to the account that owns the repository. Every plan includes a monthly pool of free minutes (2,000 on Free, 3,000 on Team) that resets each billing cycle. Standard runners in public repositories and self-hosted runners bill nothing.
That is the whole model in one paragraph. The billable surprises live in the details: rounding happens per job, not per workflow; a macOS minute costs roughly ten Linux minutes; failed jobs bill exactly like successful ones; and the free pool never covers larger runners. This article walks through each rule with the current numbers — which matter more than usual this year, because GitHub cut hosted-runner prices by up to 39% on January 1, 2026, and — in the same December 2025 announcement cycle — shelved a plan to start charging for self-hosted runners.
How billing works
On the compute side GitHub Actions meters job execution time on GitHub-hosted runners in private repositories — plus, since June 1, 2026, Copilot code review runs, which are billed per review and draw from the same plan entitlement on private repositories. Each job in a workflow is a separate metered unit — a separate billable minute counter — and the meter runs only while the job executes on the runner. Time spent waiting for a runner does not bill; queue time is a feedback-loop problem, not a billing one. Per GitHub's job execution time documentation, billable minutes exist only for private repositories on GitHub-hosted runners — there are none for public repositories or for jobs on self-hosted runners.
Two more framing facts prevent most billing confusion:
- The free pool resets monthly and does not roll over. Included minutes return to the full amount at the start of each billing cycle; unused minutes vanish.
- The dashboard now speaks in dollars. Since GitHub's move to its newer billing platform, the usage screens tend to show Actions consumption as spend rather than raw minutes, with the per-runner rates already applied. The raw minutes are still there in the usage report, but the headline number is money.
Storage — artifacts, caches, custom images — is billed separately on an hourly-accrual model and is covered below.
Per-job rounding
GitHub rounds the minutes and partial minutes each job uses up to the nearest whole minute, per the runner pricing reference. The rounding unit is the job, not the workflow, and that distinction compounds fast in exactly the architectures teams adopt to go faster.
A workflow with twelve jobs of 65 seconds each has consumed about 13 minutes of real compute — and bills 24, because each job rounds from 1:05 up to 2:00. A twenty-shard test matrix at 1 minute 10 seconds per shard bills 40 minutes for roughly 23 minutes of work. The more you parallelize into short jobs, the larger the share of your bill that is rounding overhead rather than compute. The mechanics and the mitigation math live in the CI minute rounding glossary entry.
Worth knowing for teams on both major providers: GitLab CI meters fractionally — a 90-second job costs 1.5 compute minutes there, not 2. The two systems diverge most for short, numerous jobs; the full GitLab model is covered in GitLab CI compute minutes.
OS rates and multipliers
Every runner type has its own per-minute price, determined by operating system and hardware. As of 2026-07-28, GitHub's runner pricing reference lists these rates for standard runners:
| Standard runner | Per-minute rate (USD) | Relative to 2-core Linux |
|---|---|---|
| Linux 1-core (x64) | $0.002 | ~0.3x |
| Linux 2-core (arm64) | $0.005 | ~0.8x |
| Linux 2-core (x64) | $0.006 | 1x |
| Windows 2-core (x64 or arm64) | $0.010 | ~1.7x |
| macOS 3- or 4-core (M1 or Intel) | $0.062 | ~10.3x |
For years GitHub published this OS gap as named minute multipliers — Linux 1x, Windows 2x, macOS 10x — and the January 2026 repricing folded the multipliers into direct per-runner rates (the old multiplier reference URL now redirects to the pricing table). The ratios survive in the prices: Windows time costs about 1.7 times Linux time, and a macOS minute still costs roughly ten Linux minutes, which means macOS-heavy accounts drain their included pool far faster than wall-clock time suggests. Why Apple hardware carries that premium, and what it does to an iOS team's quota, is the subject of the macOS minute multiplier entry.
The arithmetic makes the priority order obvious: a 12-minute macOS build costs $0.744 per run at list price, while the same 12 minutes on 2-core Linux costs $0.072. Moving work that does not need macOS — linting, unit tests, dependency audits — onto Linux runners is usually the single highest-leverage edit in a mobile team's workflow files.
Larger runners (extra cores, plus the GPU machines) have their own rate ladder — as of 2026-07-28, from $0.012 per minute for 4-core x64 Linux up to $0.552 per minute for 96-core Windows, with GPU Linux at $0.052 and the larger macOS machines at $0.077 (12-core) and $0.102 (5-core M2 Pro), per the same runner pricing reference. (GitHub lists the 2-core arm64 Linux runner at $0.005 among its standard runners, so it is not subject to the two rules below.) Two rules make larger runners a different billing regime entirely: included free minutes never apply to them, and they are billed even in public repositories. Every larger-runner minute is a paid minute.
Included free minutes
Each GitHub plan includes a monthly quota of minutes for standard GitHub-hosted runners in private repositories. As of 2026-07-28, per GitHub's billing documentation:
| Plan | Included minutes / month | Included artifact storage |
|---|---|---|
| GitHub Free (personal) | 2,000 | 500 MB |
| GitHub Pro | 3,000 | 1 GB |
| GitHub Free (organizations) | 2,000 | 500 MB |
| GitHub Team | 3,000 | 2 GB |
| GitHub Enterprise Cloud | 50,000 | 50 GB |
Four qualifiers on that table. The minutes apply to standard runners only — larger runners bill from the first second regardless of remaining quota. The pool is per account, shared by every private repository the account owns, so one busy repository can consume the quota for all the others. Workflows for GitHub Pages and Dependabot are free and do not draw from the pool. And since June 1, 2026, Copilot code review runs on private repositories draw from this same pool, so the quota is no longer spent by your workflows alone.
For scale: 2,000 minutes is a single 10-minute Linux pipeline running about nine or ten times per workday — 200 runs a month across roughly 21 working days. On Windows rates the same pool buys proportionally less compute, and a daily macOS build of any substance can exhaust a Free plan on its own.
When free minutes run out
What happens at zero depends on whether a payment method is on file. Without one, Actions usage in private repositories is blocked once the quota is spent, until the pool resets at the next billing cycle. With a payment method, usage continues seamlessly at the per-minute rates above — GitHub's docs illustrate a Team-plan organization using 5,000 minutes beyond quota (3,000 Linux, 2,000 Windows) and paying $38 for the month — as of 2026-07-28, per GitHub's billing documentation. Larger runners in particular require a payment method on file — confirm the current rule on GitHub's billing pages before relying on it.
GitHub can email you when included usage crosses 90% and 100% of the quota, and the billing platform supports budgets with alerts. The default worth knowing: hitting the quota with pay-as-you-go enabled does not warn loudly — the meter simply starts charging.
Do failed jobs bill?
Yes. The meter measures execution time, not outcomes, so a failed job bills every minute it ran — rounded up per job like any other. GitHub's own documentation makes the point with an example: a workflow that normally takes 10 minutes but fails at minute 5 consumes 5 minutes of quota, and the successful re-run brings the total to 15 minutes — half again the cost of a clean pass, for one transient failure.
That multiplier on failure is the quiet driver of Actions overspend. A repository with a 15% failure rate is not paying 15% extra: the failed minutes are spent either way, and if the run is re-run in full rather than re-running only the failed jobs, the failed minutes and the repeated minutes stack, and the effect concentrates in the longest workflows, where each red run is most expensive. Re-running until green adds a retry tax on top — compute spent re-executing work that already ran. What failed and repeated runs cost in engineer time as well as compute, and how to put a monthly number on it, is the subject of the cost of failed builds.
Cancelled runs
GitHub's billing docs do not address cancellation directly, but the rule they do state settles it —
billable minutes are
job execution time,
rounded up per job, regardless of outcome. A run cancelled five minutes in has executed five
minutes across its jobs, each partial job still rounds up to the next whole minute, and GitHub
documents no refund or exemption for cancelled runs. Cancellation is also not instant: GitHub sends
SIGINT, escalates to SIGTERM after 7.5 seconds, and only after a
5-minute cancellation timeout
forcibly terminates jobs still running — so a cancelled job can keep metering for several minutes
after the click, and steps guarded by if: always() are not cancelled at all. Cancelling a
25-minute build at minute 24 saves almost nothing.
Cancellations still deserve different treatment from failures in your analysis, because most of
them are good news: concurrency rules cancelling a superseded build on a rapid re-push are
converting what would have been a full-price stale run into a partial charge. A workflow-level
concurrency group with cancel-in-progress is one of the few YAML edits that reliably cuts
spend without touching test code. The diagnostic distinction — and why lumping cancellations in
with failures corrupts your failure-rate metrics — is covered in
cancelled vs failed runs.
Who pays
Minutes are charged to the account that owns the repository where the workflow runs, not to the person who triggered it. Push to a repository owned by an organization, and the organization's quota and payment method absorb the cost; the individual contributor's personal plan is never involved. GitHub's docs flag the governance consequence directly: anyone with write access to a repository can run workflows, and every cost lands on the repository owner.
Practical implications of the owner-pays rule:
- An organization's pool is shared and first-come-first-served. There is no per-team or per-repository sub-quota; a runaway matrix in one repository spends the same pool the release pipeline depends on.
- Scheduled workflows spend the owner's minutes with nobody watching. A nightly build on a dormant repository bills the organization every day it runs.
- Contributions to public repositories cost the contributor nothing — standard-runner usage in public repositories is free for everyone involved.
Public repositories
Standard GitHub-hosted runners are free in public repositories — no billable minutes, no quota draw, as of 2026-07-28. This is GitHub's structural subsidy of open source, and it extends to GitHub Pages builds and Dependabot runs.
The subsidy has one sharp edge: larger runners are always paid, public repository or not. An open-source project that switches its build to an 8-core runner for speed starts generating real charges on a repository that has never cost anything. The free ride covers the standard 2-core Linux and Windows machines and the standard macOS runner — nothing above them.
Self-hosted runners
Jobs on self-hosted runners generate no per-minute charges from GitHub — no billable minutes, no quota consumption, as of 2026-07-28. You pay for the underlying infrastructure instead: the machines, their patching, their idle time.
That "as of" qualifier is doing real work this year. In December 2025 GitHub announced a $0.002 per-minute "Actions cloud platform charge" for self-hosted runners in private repositories, effective March 1, 2026, with self-hosted usage also starting to draw from plan quotas. After substantial community pushback, GitHub postponed the self-hosted billing change to re-evaluate its approach — the hosted-runner price cuts went ahead, the self-hosted charge did not. GitHub has not said the idea is dead, so teams with large self-hosted fleets should treat "self-hosted is unmetered" as current fact rather than permanent guarantee.
Unmetered is also not the same as free. Self-hosted fleets move CI cost from a visible line item to invisible infrastructure spend — an idle runner pool sized for peak load bills your cloud provider around the clock, and no quota alert ever fires. A separate market of managed runner vendors (Blacksmith, Depot, and others) sells a middle path: faster or cheaper machines that still run your GitHub Actions workflows. Those services change the per-minute price; they do not tell you which workflows, failures, and retries are consuming the minutes — a distinction unpacked in TrimCI vs Blacksmith and TrimCI vs Depot.
The 2026 price changes
Effective January 1, 2026, GitHub reduced GitHub-hosted runner prices by up to 39%, depending on machine type. The rates quoted throughout this article are the post-cut prices. Points worth retaining from the change, per GitHub's 2026 pricing overview:
- The cut is real but uneven — "up to 39%" varies by runner size and OS, so any internal cost model built on 2025 rates now overestimates hosted spend and should be re-based on the current table.
- A $0.002 per-minute platform charge is already folded into the reduced hosted prices — it is not a separate line item for GitHub-hosted usage.
- Free quotas did not change, and standard-runner usage in public repositories stays free.
- The self-hosted charge was postponed, as covered above.
If you maintain your own cost-per-run numbers — in a spreadsheet or in a tool that converts run durations to dollars — January 2026 is the moment they silently went stale. Re-check the per-minute rate you assume against the current reference before trusting any month-over-month comparison that spans the change.
Storage and other line items
Compute minutes are the headline, but Actions bills storage separately, on an hourly-accrual model. As of 2026-07-28, per GitHub's billing documentation, artifact storage shares one pool with GitHub Packages (500 MB on Free, 2 GB on Team, 50 GB on Enterprise Cloud), with overage at $0.25 per GB-month. Actions cache storage is a separate 10 GB allowance per repository, with overage at $0.07 per GB-month — and cache overage only bills if you have raised the repository's cache limit above the included amount.
The accrual model has one counterintuitive property: deleting artifacts stops future charges but does not remove the storage already accrued this cycle. A 10 GB artifact stored for ten days has banked ten days of GB-hours whether or not it still exists on day eleven. Workflow logs and job summaries, for what it is worth, do not count against artifact storage at all.
Keeping the meter visible
Everything above explains what a minute costs. The harder operational question is where the minutes go — which repositories, which workflows, and how many of them bought nothing because the run failed, was retried, or was superseded. GitHub's billing screens total the spend by SKU; they do not connect it to failure rates, retry patterns, or duration drift, and the levers that actually shrink the bill start from exactly that connection. A practical tour of those levers — caching, path filters, concurrency, right-sizing — lives in reducing GitHub Actions costs.
TrimCI approaches the question from pipeline metadata: it syncs run and job history from GitHub Actions (and GitLab CI) through a zero-code-access integration — read-only access to Actions data, never repository contents, enforced as described on /security/ — and computes estimated compute cost from pipeline-run durations and a per-minute rate you configure per organization, alongside failure rates over decisive runs and, on GitHub Actions, the retry tax per repository (it keys on GitHub's run-attempt counter, so it is a GitHub-only measure). Fair caveats: it works at run and job granularity rather than per-test, syncs by polling rather than webhooks, and keeps at most a 60-day history window. For a first estimate of what failed and repeated runs cost your team each month, the calculator takes your team size, fully-loaded hourly cost, CI runs per day and current main-branch success rate; plan details, including what the free plan covers and how the 14-day trial works, live on /pricing/.
See what your CI failures actually cost.
Connect GitHub Actions or GitLab CI with read-only access — never your source code — and get a ranked, dollar-costed fix list from your own pipeline data.