Skip to main content

CI Runner Pricing in 2026: Depot, Blacksmith, and the Cost of Reserving Your Own Build Capacity

8 min readDora NodaDora Noda
Share
On this page

A CI bill can look beautifully linear right up to the moment someone asks, “How many runners must we have ready at once?” That question is not the same as “How many minutes did we use?” A hosted runner service can create capacity when a job arrives. A self-hosted pool has to reserve machines before the pull requests arrive.

That distinction is the entire calculation. Below is a reproducible model for standard Linux runners with 2 vCPU and 8 GB of RAM. It compares current published Depot and Blacksmith runner prices with an explicitly hypothetical reserved-node pool. It does not select a provider; it shows which inputs move each bill.

The nine-scenario answer

Start with two measurements: peak simultaneous jobs and the fraction of those slots actually busy over a 30-day month. For each scenario, total monthly runner-minutes are:

peak slots × 43,200 minutes × utilization

The reserved pool assumes one 16-vCPU/64-GB node can host five isolated 2-vCPU/8-GB runner slots after leaving practical headroom. It uses a transparent illustrative infrastructure rate of $0.05 per node-hour, or $36 for a 720-hour month. This is not a vendor quote: it is a capacity-price input readers should replace with their own provider and machine shape.

Peak jobsSlot utilizationRunner-minutes/monthBlacksmith Ubuntu x64Depot Developer*Depot Startup*Reserved nodes (5 slots/node)Reserved-node compute
210%8,640$22.56$46.56$200.001$36.00
250%43,200$160.80$184.80$292.801$36.00
280%69,120$264.48$288.48$396.481$36.00
810%34,560$126.24$150.24$258.242$72.00
850%172,800$679.20$703.20$811.202$72.00
880%276,480$1,093.92$1,117.92$1,225.922$72.00
2010%86,400$333.60$357.60$465.604$144.00
2050%432,000$1,716.00$1,740.00$1,848.004$144.00
2080%691,200$2,754.48$2,776.48$2,884.484$144.00

Here are the expressions behind the table, so the numbers are auditable rather than a screenshot of a spreadsheet:

  • Blacksmith: max(0, runner-minutes − 3,000) × $0.004 for Ubuntu x64.
  • Depot Developer: $20 + max(0, runner-minutes − 2,000) × $0.004.
  • Depot Startup: $200 + max(0, runner-minutes − 20,000) × $0.004.
  • Reserved capacity: ceil(peak jobs ÷ 5) × 720 × $0.05.

The two Depot columns are intentionally both present. Depot's current page describes Developer as a one-user plan and Startup as unlimited-user; that eligibility and the associated features, rather than minute consumption alone, determine which price applies. Treating the cheaper equation as universally available would make the comparison look more precise than it is.

The table also exposes the component a peak-only estimate loses: 20 simultaneous jobs require four nodes whether they are active 10% or 80% of the month. The runner services meter substantially different totals in those two cases; the reserved compute line stays at $144.

What the current pricing pages actually say

The original version of this question was framed around a $150 monthly charge per concurrent Depot runner. Depot's current pricing page does not present that model. It lists a $20/month Developer plan and a $200/month Startup plan, each advertising unlimited build concurrency. They include 2,000 and 20,000 GitHub Actions minutes respectively; additional GitHub Actions jobs are listed at $0.004 per minute, tracked per second. Its standard Linux runner is specified as 2 vCPU and 8 GB, which is why that shape anchors the model. Depot’s pricing page is the source for these values.

Blacksmith's live pricing page lists Ubuntu x64 at $0.004/minute and 3,000 free minutes each month. It also lists Docker layer caching and sticky disks at $0.50/GB-month, and a static IP at $100/IP-month. Those extras are deliberately not folded into the matrix because they are requirements-dependent, not inherent to every runner-minute. The rates above reflect Blacksmith’s published pricing, not a claim that performance or availability will be identical across services.

This is a useful correction beyond this one comparison: provider pricing pages evolve, so a post that treats an old plan shape as an eternal property turns a valid capacity question into a stale invoice.

The reservation tax is idle capacity, not a mystery fee

Holding peak demand at 20 slots makes the fixed-versus-variable boundary easier to see. Four nodes reserve 20 slots and cost $144 in the illustrative model. Their effective compute price per consumed runner-minute falls as more of that reservation is used.

20-slot peak utilizationRunner-minutesReserved-node effective cost/minBlacksmithDepot DeveloperDepot Startup
5%43,200$0.00333$160.80$184.80$292.80
10%86,400$0.00167$333.60$357.60$465.60
20%172,800$0.00083$679.20$703.20$811.20
50%432,000$0.00033$1,716.00$1,740.00$1,848.00
80%691,200$0.00021$2,754.48$2,776.48$2,884.48

At this particular rate and packing assumption, Blacksmith's price expression reaches $144 at 39,000 total runner-minutes, or about 4.5% of the 20-slot pool's 864,000 monthly slot-minutes. Depot Developer reaches $144 at 33,000 minutes, or about 3.8%. Depot Startup has no price-only crossing here: its $200 base price is already above the $144 illustrative capacity bill.

Those crossings are not a procurement rule. Change the node price, runner density, or needed CPU/memory and they move. A 4-vCPU build, for example, halves the five-runner packing assumption before it changes a single hosted-minute rate. A pool that is allowed to scale its nodes down at night changes the fixed side as well. The practical point is narrower: a peak number sets the machines to reserve, while utilization determines how much of that reservation becomes idle capacity.

Make the boundary fair before treating it as a cost result

The $144 node figure covers only rented compute capacity. It does not include persistent cache or artifact storage, egress, private network design, a Kubernetes control plane, a container registry, support, or the labor to patch hosts and respond to a broken runner image. Nor does it assume five jobs can safely share one node in every security model.

The managed columns also have deliberate exclusions. Blacksmith's published cache, sticky-disk, and static-IP add-ons are excluded. Depot's page separately prices cache and registry storage at $0.20/GB-month, and its Developer/Startup plans include different storage allowances. A workflow that requires a large warm cache, an IP allowlist, macOS, Windows, a GPU, or a custom image needs another row in the model—not a hand-wave that all runners cost $0.004/minute.

Isolation is another non-dollar input. A runner handling an untrusted pull request should be treated as disposable: no credentials from a prior job, no writable cache that becomes an attack path, and no long-lived host state. Hosted ephemeral runners and a well-built self-hosted system can both aim for that property, but the self-hosted side has to implement and operate it. Conversely, cache locality can materially change job duration, which changes every per-minute result. The right calculation uses observed duration after the caching and isolation design is chosen.

Autoscaling is an architecture choice beneath the price model

GitHub documents Actions Runner Controller (ARC) as its reference implementation and recommended Kubernetes-based approach for autoscaling self-hosted runner scale sets. ARC can create ephemeral runner capacity in response to queued jobs; it does not make underlying nodes appear without a capacity and machine-lifecycle strategy. GitHub’s self-hosted runner reference describes both ARC and the webhook-based alternative, including the latter's delivery-delay and reliability trade-offs.

For a Kubernetes fleet, Cluster API can manage the machines beneath that runner layer, while a cluster autoscaler or an equivalent process turns pending pods into node demand. That stack can reduce idle time, but it introduces boot time, image distribution, quota, warm-pool, and failure-recovery parameters. It should be modeled as a changed node-hour input, not advertised as a magical third billing model.

The same distinction applies to queue time. A managed service may absorb a short burst into its fleet. A self-hosted pool can hold a warm buffer, accept queueing while it adds nodes, or reserve the peak. Each policy moves a different value in the equations: peak jobs, node-hours, or job duration.

Rebuild the table from your own Actions data

Do not substitute the number of repositories, developers, or workflow runs for the three inputs that matter. GitHub's migration guidance points teams to Actions Usage Metrics for total minutes and workflow-run data; its guidance explicitly calls out peak activity as a reason to inspect concurrency. GitHub’s runner migration guide describes that measurement path.

For a real monthly model, collect:

  • p95 concurrent running jobs, not merely the all-time maximum;
  • total Linux runner-minutes and the distribution of job durations;
  • runner shapes actually required by each workflow (CPU, RAM, architecture, OS, and disk);
  • cache and artifact GB, static-IP or private-network needs, and registry traffic; and
  • the acceptable queue-time policy during a burst or a node replacement.

Then replace $0.05/hour, five runners per node, and the 720-hour convention with the actual fleet contract and packing limit. Run the table for a quiet month and a release month. The resulting values describe the trade between measured demand and reserved capacity; they do not turn one vendor’s published price into a universal answer.

Sources

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex