# GitHub Actions minutes and billing, explained

> GitHub Actions minutes are metered per job and rounded up. What the clock counts, which SKU each runner label bills as, and where the bill appears.

Source: https://latchkey.dev/learn/cost/github-actions-minutes-and-billing-explained  
Updated: 2026-09-20

GitHub Actions minutes are metered per job rather than per workflow run, and each job is rounded up to the whole minute before it reaches the invoice, so a fan-out of short jobs bills far more than a stopwatch would say. This page follows one month through that meter: what the clock counts, which billing SKU each runner label maps to, what the included minutes in your plan do and do not cover, and which columns of the usage report carry the answer.

The rate card is the easy half of an Actions bill and the half everyone reads. The hard half is the counting: the unit is a job, the rounding happens before anything is multiplied, and the number you are charged for is already larger than the number your runs page shows you.

## The unit is a job, and the clock is execution time

GitHub meters the execution time of each job on a GitHub-hosted runner and then, in the words of its pricing reference, "rounds the minutes and partial minutes each job uses up to the nearest whole minute". Two things follow from that sentence and most surprises come from one of them.

First, the rounding happens per job, not per run and not per month. A workflow of eleven jobs is eleven separate roundings, so the cost of splitting work into more jobs is paid up front in whole minutes whatever the wall clock does.

Second, the clock is execution time. GitHub's limits reference treats waiting and running as different things: a job may run for up to six hours of execution time on a hosted runner, while a job on a self-hosted runner "can be in the queue for 24 hours before it is automatically cancelled". The minutes that reach your bill are the ones a runner spent working on the job, and the usage charged is charged "to the repository owner, not the person who triggered the workflow runs".

## Rounding is a tax on short jobs, and it is bigger than it looks

Take one matrix of 20 jobs and vary only how long each leg takes. The minutes used are the stopwatch; the minutes billed are what the rounding rule produces; the cost is the billed column at the $0.006 standard Linux rate.

A 61 second job bills two minutes. Twenty of them use 20.3 minutes of machine time and bill 40, which is 97 percent more than the work took. At 25 seconds a leg it is 140 percent more, at three minutes and one second 33 percent, and at nine and a half minutes 5 percent. The tax is not a fixed percentage, it is a fixed amount of waste per job, so it lands hardest exactly where teams have been told to optimize: more parallelism, shorter jobs.

The reading is not "never parallelize". A matrix leg under a minute is nearly free to run and never free to bill, so collapsing trivial legs into real ones is a saving you can compute before you make it.

| Each of 20 jobs takes | Minutes used | Minutes billed | Billed at $0.006 |
| --- | --- | --- | --- |
| 25 seconds | 8.3 | 20 | $0.12 |
| 61 seconds | 20.3 | 40 | $0.24 |
| 3 minutes 1 second | 60.3 | 80 | $0.48 |
| 9 minutes 30 seconds | 190.0 | 200 | $1.20 |

> Computed from the rounding rule in [Actions runner pricing](https://docs.github.com/en/billing/reference/actions-runner-pricing), read 20 September 2026. Minutes used is 20 times the job length; minutes billed is 20 times that length rounded up to a whole minute.

## Every runner label bills as a named SKU

The label you type in `runs-on` picks a machine, and the machine has a billing SKU. That SKU is the string that appears on the usage report, so it is the join between a workflow file and a line on an invoice. Knowing it turns "where did the money go" into a spreadsheet filter.

The larger runners follow the same scheme with their core count in the name, from `linux_4_core` at $0.012 a minute to `linux_96_core` at $0.252, and the two larger macOS machines are `macos_l` at $0.077 and `macos_xl` at $0.102. The rates and the rules behind them are on [how GitHub Actions pricing works](/learn/cost/github-actions-pricing-explained).

| What you type in runs-on | Billing SKU on the report | Per-minute rate |
| --- | --- | --- |
| `ubuntu-slim` | `actions_linux_slim` | $0.002 |
| `ubuntu-latest` | `actions_linux` | $0.006 |
| `ubuntu-24.04-arm` | `actions_linux_arm` | $0.005 |
| `windows-latest` | `actions_windows` | $0.010 |
| `windows-11-arm` | `actions_windows_arm` | $0.010 |
| `macos-latest` | `actions_macos` | $0.062 |

> SKUs and rates read from [Actions runner pricing](https://docs.github.com/en/billing/reference/actions-runner-pricing) and labels from [GitHub-hosted runners](https://docs.github.com/en/actions/reference/runners/github-hosted-runners), both on 20 September 2026.

## What the included minutes cover, and the four things they do not

Your plan comes with a monthly quantity of minutes for standard GitHub-hosted runners in private repositories, and that quantity resets at the start of each billing cycle. It is stated in minutes rather than in dollars, and GitHub publishes no per-operating-system conversion for those minutes, so read the allowance as a minute count rather than as an amount of money.

Everything else is outside it, and each of the four exclusions below has caught somebody. The last one is the friendliest: self-hosted usage is not metered at all, so it neither costs money nor eats the allowance.

- Larger runners: "Included minutes cannot be used for larger runners", so a job that moves up a size starts billing from its first minute.
- Storage: artifacts and Packages share one allowance and the Actions cache has its own, each with its own per-GB rate, measured hourly rather than monthly.
- Public repositories: standard runners there are free and unlimited, so they never touch the allowance in the first place.
- Self-hosted runners: "GitHub Actions usage is free for self-hosted runners", so those minutes are not metered and draw nothing from the quota.

> Quoted from [Actions runner pricing](https://docs.github.com/en/billing/reference/actions-runner-pricing) and [GitHub Actions billing](https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions), read 20 September 2026.

## Where the bill actually appears

The dashboard shows totals. The usage report shows lines, and lines are what you need. GitHub publishes three of them: a summarized report covering up to a year, a detailed report covering at most 31 days, and an AI usage report. The detailed one is the only one that names the workflow, and reports arrive by email to the address on your account rather than downloading in the browser.

Six columns carry an Actions answer. Read `sku` first, because it tells you which machine ran the work, and `workflow_path` second, because it tells you which file asked for it. The pairing of those two is what separates a Linux job that costs a tenth of a cent from a macOS job in the same repository.

| Report column | What it holds on an Actions line |
| --- | --- |
| `sku` | The runner SKU that ran the job, for example `actions_linux` or `linux_16_core` |
| `quantity` and `unit_type` | Billed minutes, already rounded up job by job |
| `applied_cost_per_quantity` | The per-minute rate that line was charged at |
| `discount_amount` | Free usage priced then discounted, which is how public-repo and self-hosted minutes appear |
| `workflow_path` | The workflow file that produced the usage, in the detailed report only |
| `net_amount` | What that line actually adds to the invoice |

> Column names and report limits read from [GitHub usage reports](https://docs.github.com/en/billing/reference/usage-reports) on 20 September 2026.

## One month, counted the way the meter counts it

Take a private repository that runs 250 workflow runs a month. Each run is a 12 leg test matrix at 3 minutes 20 seconds a leg, plus one build job of 6 minutes 30 seconds. Every leg rounds to 4 minutes and the build job rounds to 7, so a run bills 55 minutes and uses 46.5.

Across 250 runs that is 13,750 billed minutes against 11,625 used, an overhead of 2,125 minutes or 18.3 percent. At the standard Linux rate of $0.006 the month is $82.50, where the stopwatch figure would have been $69.75: the rounding alone is $12.75. On a GitHub Team plan the first 3,000 minutes are included, so the invoice is 10,750 minutes at $0.006, which is $64.50.

Now price the same 13,750 billed minutes on a Latchkey small runner at the published $0.0025 a minute. The compute line is $34.38, and on top of it sits the monthly plan fee, which is $5 on Developer, $19 on Launch and $49 on Scale. Latchkey's own included minutes, 2,000 to 6,000 a month depending on plan, are not netted off here. So the all-in month is $39.38, $53.38 or $83.38 against GitHub's $64.50: lower on the two smaller plans, higher on Scale unless you are using the 6,000 minutes that plan prepays. That is the shape of every honest comparison at this volume, and [how Latchkey cuts the GitHub Actions bill](/github-actions-cost-reduction) is the case for the volumes where the gap widens.

Whichever way that lands, the 2,125 rounded-up minutes are waste on both price lists. Consolidating the 12 legs into 6 legs of about 6 minutes 40 seconds bills 42 minutes for the legs instead of 48, so a run falls from 55 billed minutes to 49. That is 1,500 minutes a month, or $9.00, for exactly the same tests.

## FAQ

### What counts as a GitHub Actions minute?

A minute of execution time on a GitHub-hosted runner, measured per job and rounded up to the next whole minute. Queue time is a separate thing in GitHub's own limits documentation, which allows a self-hosted job to sit in the queue for 24 hours and a hosted job to run for six hours. The account that owns the repository is charged, not the account that pushed.

### Are GitHub Actions minutes counted per job or per workflow run?

Per job. Each job in a run is rounded up to a whole minute on its own, so a run with twelve jobs is twelve roundings. This is why adding matrix legs can raise the bill while lowering the wall clock, and why collapsing very short legs into fewer, longer ones is usually the cheapest change available on a Linux pipeline.

### Why does my usage report show more minutes than my jobs ran?

Because the report shows billed minutes, which are already rounded up job by job. A matrix of twenty 25 second jobs uses 8.3 minutes of machine time and reports 20. The gap is not an error and there is no setting for it; the only lever is job length, since the waste is a fraction of a minute per job however short the job is.

### Can I buy more GitHub Actions minutes?

Not as a pack. Once the included minutes for the cycle are gone, further standard-runner usage on private repositories simply bills at the per-minute rate for whichever runner ran it, provided the account has a valid payment method. Without one, GitHub blocks usage rather than billing it, which is the behavior [running out of minutes](/learn/cost/github-actions-out-of-minutes) covers.

## References

- [GitHub: Actions runner pricing, per-minute rates, billing SKUs and the rounding rule (verified 2026-09-20)](https://docs.github.com/en/billing/reference/actions-runner-pricing)
- [GitHub Actions billing: included minutes, storage and what is free (verified 2026-09-20)](https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions)
- [GitHub: usage report types, columns and retention (verified 2026-09-20)](https://docs.github.com/en/billing/reference/usage-reports)
- [GitHub Actions limits: execution time, queue time and concurrency (verified 2026-09-20)](https://docs.github.com/en/actions/reference/limits)
- [Latchkey pricing: published per-minute runner rates and plan fees (verified 2026-09-20)](https://latchkey.dev/pricing)

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
