How Do I Forecast Runner Spend?
Forecast runner spend by pricing last month's billed minutes per label at the published rate, then scaling by planned job growth rather than by headcount.
Forecast runner spend by taking the billed minutes on each runner label from the last full month, applying that label's per-minute rate, and multiplying by a growth factor drawn from planned job count. Scale by job count rather than by headcount, because the bill has no seat term to grow.
Answer
The forecast is one row per runner label and one line of arithmetic:
quarterly spend = sum over labels of (minutes last full month x rate per minute x growth factor x 3)Three inputs feed each row. Minutes per label come from your own billing history. The rate comes from the pricing page. The growth factor comes from what the roadmap says will happen to job count on that label: a matrix that gains shards, a new repository joining the same workflow, a path filter loosening.
Every label prices independently, so the growth factor applies where the growth actually lands. Here is a fleet merging roughly 200 pull requests a month, forecast one quarter ahead.
| Runner label | Minutes last full month | Rate | Growth factor | Forecast per month | Forecast per quarter |
|---|---|---|---|---|---|
warp-ubuntu-latest-x64-2x | 1,200 | $0.004/min | 1.15 | $5.52 | $16.56 |
warp-ubuntu-latest-x64-4x | 3,600 | $0.008/min | 1.15 | $33.12 | $99.36 |
warp-ubuntu-latest-x64-8x | 8,800 | $0.016/min | 1.50 | $211.20 | $633.60 |
warp-macos-latest-arm64-6x | 1,620 | $0.08/min | 1.00 | $129.60 | $388.80 |
warp-windows-latest-x64-4x | 1,100 | $0.016/min | 1.15 | $20.24 | $60.72 |
| Runner minutes | 16,320 | $399.68 | $1,199.04 |
Rates checked on 2026-08-13 against the pricing page. The same minutes at a flat growth factor of 1.00 would forecast $964.80 for the quarter, so the growth assumptions are worth $234.24 on their own and deserve to be written down where a reviewer can argue with them.
Add the usage items that bill alongside minutes. At 40 GB-month of cache storage the cache line is $8.00 at $0.20 per GB-month, and 150,000 cache reads and writes add $15.00 at $0.0001 per operation, both rates from the pricing page checked on 2026-08-13, so $23.00 a month and $69.00 for the quarter. The forecast lands at $1,268.04. Signup includes $10 free credits, and the rate for every line item above is on the pricing page.
Detail
Where each input comes from
Minutes per label come from the Billing section of Reports, where the CI tab carries one row per job execution with repository, job name, runner label, stack, execution time, billed time, and the cost split between runner and snapshot. Use billed time rather than execution time, since billing is per minute and a 35 second job bills a full minute. Every tab exports to CSV with all rows matching the current filters, so the forecast starts as a spreadsheet with one row per job.
The growth factor is the only input you invent, so give it a source too. Read it off planned work: three new services adopting the shared workflow, an integration matrix widening from four shards to six, a nightly job moving to every pull request. A factor with a named cause survives review; a factor of 1.2 with no cause behind it is a guess wearing a number.
The two drivers that move the number most
Matrix width is the first. The integration shards row above is 200 pull requests a month against a 4-way matrix, so 800 job executions at 11 billed minutes each, which is 8,800 minutes at $0.016 per minute, or $140.80. Widening the matrix to 6 shards makes it 1,200 executions and 13,200 minutes, or $211.20 a month. That single change is the 1.50 factor in the table, and it adds $211.20 to that label's own quarterly forecast on its own, the largest piece of the $234.24 that growth assumptions add across the whole table. Matrix width multiplies job count directly, and job count is the term that per-minute rounding also amplifies.
Re-run rate is the second. Track the share of workflow runs that are a second or later attempt on the same commit. Moving that share from 12 percent to 20 percent multiplies minutes on the affected labels by 1.20 divided by 1.12, which is 1.07, and a flaky suite can cross that gap in a single quarter without anyone filing a ticket. Duplicate triggers behave the same way: a workflow firing on both push and pull_request for the same branch doubles the run count on every label it touches.
Neither driver shows up in a headcount model, which is why headcount models drift.
Refresh the forecast from the API
Create a key with the ci scope from the API keys page, following the automation documentation, then pull daywise costs for the window you are forecasting.
curl -sS -G 'https://api.warpbuild.com/api/v1/jobs/daywise-costs' \
-H 'Authorization: Bearer wkey-xxxx' \
-H 'Accept: application/json' \
--data-urlencode 'start_date=2026-10-01T00:00:00Z' \
--data-urlencode 'end_date=2027-01-01T00:00:00Z' \
| jq -r '.[] | [.date, .amount, .cumulative_amount] | @tsv'The response is one row per day carrying date, amount, and cumulative_amount, which is exactly the shape a burn-down needs. Take the last cumulative_amount, divide by elapsed days, and multiply by the days in the quarter. On day 20 of a 92 day quarter, a cumulative amount of $268.40 paces to $1,234.64, about 3 percent below the $1,268.04 forecast above. Run that check weekly on a schedule and the forecast stops being a document.
What never enters the forecast
Pricing is purely usage based. There is no base subscription fee, no platform fee, and no seat fee (pricing page), so the model has no fixed term, no per-user term, and nothing to renegotiate when the team grows. Adding a repository adds cost only when it queues jobs, and archiving one removes its minutes from the next invoice.
Every figure on this page carries a number, a source, and a checked-on date, and a forecast that holds itself to the same standard is one a finance reviewer can accept without rebuilding it.
Related Questions
Should I forecast runner spend by headcount or by job count?
By job count. Pricing is purely usage based, with no base subscription fee, no platform fee, and no seat fee, so a team growing from 40 to 60 engineers changes the forecast only through the extra workflow runs those engineers trigger. Every rate that feeds the model sits on the pricing page, and the bill estimation answer covers the single-month version of the same arithmetic.
What growth factor should I use if there is no plan to read?
Take the trailing three months of billed minutes per label, compute the month over month change for each label, and use that as the factor where no planned change exists. Cap it at the point where the label would exceed its budget and treat the cap as a review trigger rather than a prediction. The minutes budget guide covers how to set those per-label ceilings.
How often does a quarterly runner spend forecast need refreshing?
Once a month for the inputs and once a week for the pace check. Re-export the Billing rows from Reports monthly to refresh minutes per label, and run the daywise costs pull weekly to compare pace against the forecast line. A pace more than 10 percent above the forecast almost always traces back to matrix width or re-run rate. To turn the same rows into a per-change number, divide each label's forecast by the pull requests that trigger it, which the cost per pull request guide works through in full.
Start with $10 in free credits
Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.