Pricing
One meter. Both halves of the product.
No monthly fee. 3,000 run-minutes included every month, for every organisation. Beyond that, $0.0040 a run-minute — the same rate whether it is a test suite or a terraform apply.
And what that buys you
The same three open-source projects, built with their own CI commands, on every provider we currently benchmark, 4 times a month. Times are the whole job — queue, provisioning, dependencies and build — read from GitHub’s own records rather than reported by the runners.
| Provider | Machine | eslint | cargo | prometheus | actionlint | Queue | Swing | Overall | Per minute | Cost per build |
|---|---|---|---|---|---|---|---|---|---|---|
| runners.io every row above the paused ones is measured against this row | 2 vCPU / 8 GB | 157s 140–482s | 255s 246–323s | 175s 157–559s | not run | 36s | ±256% | baseline | $0.004 | $0.012 |
| Blacksmith not measured in this window | 2 vCPU / 8 GB | — | — | — | — | — | — | — | $0.004 | — |
| GitHub-hosted | 2 vCPU / 8 GB | 197s+25% 168–227s | 561s+120% 354–628s | 270s+54% 196–352s | not run | 27s | ±80% | 1.67× slower | $0.006 | $0.034+183% |
| PausedOur benchmark of these providers is paused. Each row is that provider’s last figures, dated, and is not compared with the rows above. | ||||||||||
| Namespace paused, last measured 2026-09-22 median of 42 rounds, 2026-09-07 to 2026-09-22 | 2 vCPU / 8 GB | 158s 131–204s | 330s 276–437s | 203s 170–300s | not run | 35s | ±76% | not compared | $0.006 | $0.020 |
How this was measured, what machine each provider gave us, and where we do not win
Every percentage is against our own row, and on all of these columns less is better — so a positive number is slower or dearer than us, and a negative one beats us. Read the four rows here as four rows, not as the market: Ubicloud was on this table until 25 August 2026 and cost less per build than we do, and we removed them in the same change that raised our own rate from $0.003 to $0.004 a minute. Shorter bar is better: each is drawn against the slowest row in its own column, which is why a bar cannot be compared across columns — a cargo build takes minutes and an eslint run takes seconds. Colour grades the gap on a fixed scale: yellow is level with us, orange half behind, red twice the time or the price. Our own row is the mark everything is set against and is shown green; on any other row green would mean that provider beat us, and nothing earns it for merely keeping up.
Machine is the shape each provider advertises, at the label the benchmark asked for. Every row here is the same shape. GitHub’s is the private-repository runner; a public repo gets 4 vCPU / 16 GB and that row would move. One row cannot be checked from the workflow file at all, because its label does not decide the machine: Namespace’s names a profile configured in their dashboard — it was 4 vCPU until 2026-08-23, and those figures were discarded rather than compared against 2 vCPU machines.
What arrives is not always what is advertised. Probed inside every timed job by saturating every visible core, we deliver 1.9 of our 2 advertised cores and GitHub delivers 1.8 of its 2. Both are medians over the 44 approved rounds from 2026-09-07 to 2026-10-08 in which our guest was shown the 2 vCPU we sell. Rounds before 2026-09-07 18:45 UTC ran our guest with 4 vCPU rather than the 2 we sell, and were withdrawn from this comparison because that machine is no longer sold.
Times are end-to-end wall clock — from the workflow being created to the job finishing, including queue, provisioning, checkout, toolchain, dependencies and build. They are read from GitHub’s own API rather than reported by the runners, so no provider times itself, ourselves included. GitHub-hosted is not the reference row, but it is measured exactly the same way: if that is what you run today, read that row. The cost column is not end to end; it is worked out from billed time only, below.
Queue is how long a job waits before a machine picks it up — created to started. It is already inside the workload times to its left, not added to them, so do not count it twice. Nobody charges for it, ourselves included: our meter starts when your code starts, so queue never reaches the cost column. It is here because your pull request is blocked for it either way, and a runner that is quick once it starts but slow to find you a machine is not a quick runner. The figure is a typical wait rather than a worst case: a job that queued three or more times its own provider’s median queue is dropped, and the longest wait it removed on this data was 95 seconds.
Cost per build is worked out only from the time each provider bills: the job itself, from the moment a machine picks it up to the moment it finishes, as GitHub records it. Queue is in no row’s cost, ours included. Each provider’s minutes follow that provider’s own billing rule: we round each job up to the whole minute, with a one-minute minimum; Blacksmith has stopped publishing a rule, so we use the last one it did, to the nearest minute, which is the reading that costs them least; Namespace bills at least a minute, then drops a part-minute of up to 15 seconds and rounds any other part-minute up; GitHub rounds each job up to the whole minute. Each workload’s median job is billed under that rule at the provider’s published rate for the exact machine it was benchmarked on, and the workloads are averaged. Every row is the pay-as-you-go rate — what a minute costs someone who signed up and ran a build, with no commitment — which is not always a provider’s headline 2 vCPU price. Namespace charges on max(vCPU, RAM ÷ 2), so the 8 GB every other row includes at the 2 vCPU price bills as four units on theirs; their prepaid rate would put them a third lower, but it needs a $100 monthly commitment the others do not ask for.
Every provider’s configuration, in full. The benchmark is built to measure a cold build on every row: it never calls actions/cache, dependencies are fetched fresh each run, and toolchains are installed by each project’s own workflow. Anything that would carry state from one run into the next is turned off, so that a row measures a provider rather than that provider’s history. That is also the reason some of their features do nothing here, which we would rather say than let a cold run be mistaken for a full product comparison.
| Provider | Configuration |
|---|---|
| runners.io |
|
| Blacksmith |
|
| Namespacepaused; as configured when last measured |
|
| GitHub-hosted |
|
Each figure is the median of the rounds that provider completed, taken from 44 rounds between 2026-09-07 and 2026-10-08 — the window reaches about 55 days back from the newest round, so older rounds stop counting — with the observed range beneath it and the worst swing in its own column — the most recent run. The paused rows are not part of that comparison. Each is the median of the rounds that provider completed over the same span, measured back from its own last round and dated on its row. None is compared with ours, and none is counted in any figure above it. Providers miss rounds: a runner is never scheduled, a build falls over. So a comparison uses only the rounds both providers ran, recomputed rather than read off the two medians above — otherwise a provider that happened to miss the busy hours would be judged on its good ones. Rounds are never discarded for being incomplete; the round nobody finished is the one worth keeping. Not run means no provider completed that workload in the rounds a row rests on: the benchmark did not run it then, so it counts against nobody. The thinnest comparison here rests on 43 shared rounds. Rounds are taken 4 times a month, each at a different hour (04:17, 09:17, 14:17 and 20:17 UTC), so working hours are in the sample as well as the quiet hour: a benchmark run only at 04:00 measures the one time nobody’s CI is busy. Rounds before October 2026 were taken four times a day. Rounds that flatter us least still count — publishing only a favourable hour would be true and indefensible at once. One exclusion, applied to everybody. A job whose queue was at least three times that provider’s own median queue is dropped — that is GitHub’s scheduler, not the machine we are measuring. It is keyed to each provider’s own behaviour rather than to a round, so it cannot remove our bad day and keep a competitor’s. In this sample it removed 1 job: GitHub-hosted (1).
What we deliberately do not bill you for
Queue wait. Sandbox cold start. Control-plane API calls. State reads and writes. The clock starts when your engine process starts and stops when it exits, so none of these has a process running to measure.
Provider downloads from our mirror happen during terraform init, which is your engine running — so they are inside the run minute, like everything else init does. What we never do is add a line for them: no bandwidth charge, no per-request charge, and the mirror is there to keep the download short rather than to bill it.
Both lists exist because a minute-based meter has an obvious hazard: if the platform is slow, we get paid more. Every second of latency we introduce is on our side of the line, and every second we remove costs us money. The one place that argument is weaker is the mirror: a provider download is inside your run minute, so we run our own and keep it close rather than asking you to take the timing on trust.
What it replaces
Two worked examples. Every quantity is something you can count on your own account — builds, how long they take, applies, and the size of the estate Terraform manages. Swap in your own numbers and the arithmetic moves the way you would expect.
| A month that looks like this | GitHub-hosted + HCP Terraform | Blacksmith + HCP Terraform | Here |
|---|---|---|---|
| A small team 400 builds at 6 minutes, 60 Terraform applies at 2 minutes, over 400 managed resources. 2,520 run-minutes here, both engines together. | $40/mo $40 of it is Terraform, billed on estate size whether you ran an apply or not. | $40/mo Same Terraform bill — their runners do not run it either. | $0/mo Inside the included allowance. |
| A busy team 2,000 builds at 6 minutes, 120 Terraform applies at 2 minutes, over 1,400 managed resources. 12,240 run-minutes here, both engines together. | $194/mo $140 of it is Terraform, billed on estate size whether you ran an apply or not. | $176/mo Same Terraform bill — their runners do not run it either. | $36.96/mo 9,240 minutes past the allowance. |
Rates read from each provider’s own pricing page on 2026-08-25; ours from the row that bills it. HCP Terraform is quoted at Essentials, their cheapest tier at $0.10 per resource per month — Standard is $0.47 and Premium $0.99, so this is the smallest their column can honestly be. GitHub is quoted on Team, whose 3,000 included minutes match ours. Per-seat fees are excluded from every column, ours included. Applies are counted at two minutes because that is what a small plan-and-apply costs in wall clock; a large estate takes longer on every platform, including this one. If your Terraform estate is small the right-hand columns shrink — the point is not the total, it is that two of these columns are two bills and one is one.
Every provider, every feature
The rates have converged — four of these charge exactly what we do. So the question is what you get for it, and the row we care most about is the first one.
| runners.ioCI and Terraform | GitHub-hostedCI only | BlacksmithCI only | BuildJetCI only | WarpBuildCI only | DepotCI only | NamespaceCI only | HCP TerraformTerraform only | SpaceliftTerraform only | |
|---|---|---|---|---|---|---|---|---|---|
| GitHub Actions runnersEvery figure here is the same machine — 2 vCPU Linux x64 — so the columns compare like for like. | |||||||||
| Per minute2 vCPU Linux x64 | $0.004 | $0.006 | $0.004 | $0.004 | $0.004 | $0.004 | $0.006 | — | — |
| Before the first minuteLowest monthly fee carrying that rate | nothing | nothing | nothing | nothing | nothing | $20/mo | nothing | — | — |
| Included minutes a month | 3,000 | 3,000 | 3,000 | none | none | 2,000 | none | — | — |
| DiskOn the 2 vCPU runner | 80 GB | 14 GB | 80 GB | 64 GB | 150 GB | 100 GB | 48 GB | — | — |
| MemoryOn that same runner | 8 GB | 8 GB | 8 GB | 8 GB | 8 GB | 8 GB | 4 GB | — | — |
| Largest size | 16 vCPU | 64 vCPU | 32 vCPU | 32 vCPU | 32 vCPU | 64 vCPU | 32 vCPU | — | — |
| Concurrent jobs | 20 jobs | 20–180 by plan | Unlimited | – | – | No stated limit | – | — | — |
| One clean VM per jobNever reused between jobs | ✓Its own virtual machine, which no other job uses, destroyed when the job ends. Never reused. | ✓ | ✓ | – | ✓Ephemeral VMs. | ✓Single-tenant ephemeral EC2. | ~Container, not a VM — it reported `docker` when probed. | ✗ | ✗ |
| Actions cache | ✓Included. Not metered. | ✓10 GB per repository. | ✓Included; they state 400 MB/s. | ✓20 GB per repository per week, free. | ✓$0.20/GB-month plus $0.0001 per operation. | ✓25 GB included on Developer, then $0.20/GB-month. | ✓Snapshots $0.002/GB-hour, storage $0.0048/GB-day. | ✗ | ✗ |
| Docker layer cache | ✓$0.50/GB-month. | ✗No managed layer cache. | ✓$0.50/GB/month. | – | ✓Docker builders, 100 GB–2 TB. | ✓Shares the same storage allowance. | ✓Remote Docker builder. | ✗ | ✗ |
| Sticky disk | ✓$0.50/GB-month, billed on what you use. Reclaimed after 7 days idle. | ✗ | ✓$0.50/GB/month. | – | ✗Runner storage is ephemeral. | – | ~Cache Volumes persist at the filesystem level. | ✗ | ✗ |
| Static egress IP | ✓$100/month per organisation. Requesting is self-service; provisioning the address is still manual. | ~Larger runners only, Team and above. | ✓$100/IP/month. | – | – | ~Egress filtering rather than a fixed address. | – | ✗ | ✗ |
| ARM | ✗x64 only. | ✓$0.005/min at 2 cores. | ✓$0.0025/min. | ✓Same rate, but 3 GB RAM at 2 vCPU. | ✓$0.003/min at 2 vCPU. | ✓Graviton4, same rate as x86. | ✓AmpereOne and Apple silicon. | ✗ | ✗ |
| Windows or macOS | ✗Linux only. | ✓Both. | ✓Windows in public beta; macOS on M4. | ✗Neither. | ✓Windows Server 2022/2025; macOS on M4 Pro. | ✓Both. | ✓Windows 2×, macOS 10× multiplier. | ✗ | ✗ |
| Nested virtualisationKVM inside the job, for Android emulators. Not Docker — that works everywhere here | ✗No /dev/kvm in the guest. Docker containers are unaffected. | – | ✓KVM on x64 Linux. | ✓AMD only; hardware-accelerated Android emulation. | – | – | – | ✗ | ✗ |
| GPU runners | ✗ | ✓GPU-enabled larger runners. | ✗ | ✗ | – | ✓Business plan. | – | ✗ | ✗ |
| SSH into a running job | ◑In build. Not available yet. | ✗Third-party actions only. | ✗ | – | – | – | ✓SSH and remote display into a running job. | ✗ | ✗ |
| Terraform / OpenTofuThe same columns, scored on the other half of the job. This section is mostly crosses, and that is why the two halves are on one table rather than two. | |||||||||
| Runs Terraform or OpenTofu | ✓Same meter, same allowance, same bill as CI. | ✗No managed state, registry or policy. You can run the binary yourself. | ✗Not offered. | ✗Not offered. | ✗Not offered. | ✗Not offered. | ✗Not offered. | ✓The incumbent. Terraform, not OpenTofu. | ✓Also Terragrunt, Pulumi and Kubernetes — wider than ours. |
| Billed on | Run-minutes — the same ones CI uses | — | — | — | — | — | — | Resources under management, from $0.10 each per month | Private workers; Starter+ from $20,000 a year |
| Remote state storage | ✓Versioned, with soft delete and restore. | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ |
| Plan on pull request | ✓GitHub, GitLab and Forgejo. | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓Speculative plans on pull requests. | ✓ |
| Private module registry | ✓Private registry, and a provider mirror. | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓Business plan and above. |
| Policy as code | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓Sentinel and OPA; one policy set free. | ✓OPA; Starter+ and above. |
| Drift detection | ◑Planned, not started. Not available yet. | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓Health assessments — Standard or Premium only, so $0.47–$0.99 a resource rather than $0.10. | ✓Starter+ and above — from $20,000 a year. |
| Read from | this page | their docs | their docs | their docs | their docs | their docs | their docs | their docs | their docs |
✓ offered · ~ partly, see the note · ◑ not available yet — the note says whether it is in build or planned · ✗ not offered · – we could not find it published, which is not the same as it not existing · — they do not sell this kind of thing at all. Nothing marked ◑ carries a price, and it appears only on our own row — we have no way of knowing what anyone else has under way.
Runner rates and shapes are the 2 vCPU Linux x64 figure so the columns compare the same machine; ARM and larger sizes are priced differently by everyone here, and Namespace’s smallest standard shape carries 4 GB rather than 8, which the memory row shows. Per-seat fees are excluded from every column, ours included. HCP Terraform and Spacelift are not given a per-minute rate because they do not sell one — they bill per resource and per worker, and inventing a figure for them would not be a comparison. Read from each provider’s own documentation on 2026-08-25; if we have something wrong we would rather hear it than leave it up — tell us.
The awkward questions
- Is there a free tier?
- 3,000 run-minutes every month, at no charge — but a card is required to start, and adding one places a $5.00 authorisation that we release immediately and never charge. Free compute with internet egress attracts mining, and every provider that offered it without a card has had to withdraw it. The card is the deterrent; the minutes are not the thing we were protecting. The one exception is ours: the probe accounts we run against this platform sit on a named internal plan — capped, never invoiced, and not a plan a customer account can be moved onto.
- What happens if I go over?
- Nothing stops. Minutes beyond the allowance are billed at $0.0040 each, and the usage screen shows the projection before the invoice does.
- Do you charge per user?
- No. Invite everyone — reviewers, contractors, the person who only ever looks at a failed build.
- Do you charge per resource under management?
- Never. The size of your Terraform estate costs you nothing here; only the compute that changes it does.
- Is CI billed differently from Terraform?
- No, and that is the point of the unit. A test suite and a
terraform applydraw on the same allowance at the same rate.