CI cost study: GitHub-hosted runners vs our AWS machines

What a day of CI actually costs, before the move to our own machines and after every improvement since. Real bills from GitHub and AWS, normalized per run and per merge.

Measured 2026-10-04 · window Sep 22 – Oct 4 · gross cost, before any credits · sources at the bottom · Oct 4 (*) is a partial Sunday and is shown but not used in any conclusion

AnswerDaily billPer runWhat moved the numberThin queueGap to targetMethod and sources

Answer

CI is about 2.6x cheaper per run than on GitHub-hosted runners, and about 2.8x cheaper per merge. A full weekday of CI cost $738 on GitHub (Sep 22–26 average). The same volume on our machines, at Friday Oct 3's rate, costs about $281. The earlier "$203 a day, flat" figure was after AWS credits; these are the real numbers.

$0.30 → $0.11
cost per CI run (GitHub era → Oct 3)
$2.52 → $0.88
cost per merged PR
$738 → $281
a weekday of CI, same volume (2,489 runs)
$65
the daily target ($2k/month). Still 4x above it.
Full study (sections 2 onward)

Daily bill, both providers

$46409/22T$71709/23W$105309/24T$92209/25F$53309/26S$26009/27S$103609/28M$60109/29T$42109/30W$41710/01T$73010/02F$41310/03S$6910/04S$0$250$500$750$1000→ AWS machinesmerge queuethin queueGitHub-hosted runnersAWS (our machines), CI share

Grey = GitHub Actions hosted-runner charges (gross, from GitHub's billing API). Purple = the CI share of the AWS bill: total AWS gross minus the $53/day the product itself costs with no CI on AWS (median of Sep 22–28). Dashed lines mark the move to AWS machines (Sep 29), the merge queue (Oct 1) and the thin queue (Oct 4, 08:22 UTC).

PeriodDaysCI $/dayCI runs/day$ per run$ per merge
GitHub-hosted (before)Sep 22–26, weekdays$7382,489$0.296$2.52
Just moved to AWSSep 29–30$5113,656$0.140$1.36
Merge queue + 64-coreOct 1–2$5734,900$0.117$1.12
All improvements (after)Oct 3, Fri$4133,656$0.113$0.88
Sunday Oct 4 *Oct 4, partial$691,233$0.056$0.49

"CI runs" = runs of the main CI workflow (ci.yml), all triggers. Oct 2 includes the 64-core machines running the full suite on every merge-queue train; that is what the thin queue removed.

Cost per run, day by day

$0.00$0.20$0.40$0.2609/22$0.2709/23$0.3009/24$0.3109/25$0.3409/26$0.1709/29$0.1109/30$0.0910/01$0.1410/02$0.1110/03$0.0610/04 *CI cost per CI run (GitHub + AWS, all CI, per run of the main CI workflow)

Traffic varies a lot by day (1,200 to 5,400 CI runs), so the per-run number is the fair comparison. It fell by about half the day we moved to AWS, and has drifted down since as more of the fleet ran on spot.

What moved the number (AWS era)

A day of EC2 cost is runs × work per run × price per unit of work. Each improvement maps to one factor.

DayCI runsvCPU-hours per run$ per vCPU-hourSpot share of $64-core share of workQueue runs per mergeEC2 $
09/293,5112.5$0.027833%0%0.0$243
09/303,8022.7$0.033331%0%0.1$339
10/014,4092.7$0.025363%0%1.2$299
10/025,3905.1$0.022039%49%5.1$609
10/033,6564.9$0.018158%54%2.0$324
10/04 *1,2333.8$0.014393%59%2.7$67

Thin queue (merged Oct 4, 08:22 UTC)

Gap to the $2k/month target

Where a weekday stands (Oct 3 rate)

EC2 $324 + AWS overhead $52 + residual GitHub $37 ≈ $413/day. About $12k/month at weekday pace.

What would have to go, in order of size

1. On-demand → spot (~$82/day). 2. 64-core full suite out of the queue (~$110/day; the thin queue's job). 3. Queue restarts 2.0 → ~1.2 per merge. 4. Public IPv4 and NAT (~$30/day).

Even with all four, a weekday lands near $150–200 of CI, not $65. Reaching $65 needs fewer runs per PR, not cheaper machines. That is a product decision, not a tuning one.

Method and sources

NumberSourceLabel
GitHub $/day, hosted minutesGitHub billing usage API, org PropFlow-Technologies, product=actions, gross amount, by dayHARD
AWS $/day by service, instance type, purchase type, regionAWS Cost Explorer, unblended cost, RECORD_TYPE Credit/Refund excluded, dailyHARD (Oct 4 partial; Cost Explorer lags some hours)
CI share of AWSAWS total gross minus $53/day product baseline (median of Sep 22–28, when no CI ran on AWS)ESTIMATE
CI runs, merge-queue runs per dayGitHub Actions API, workflow ci.yml, counted in 6-hour windows (the API caps a single count at 2,500)HARD
Merged PRs per dayGitHub search API, is:merged merged:DAYHARD
vCPU-hoursCost Explorer instance hours × vCPUs of the instance sizeHARD
Weekday projectionOct 3 cost per run × GitHub-era weekday run volumeESTIMATE

Why gross: AWS credits ($5k pool) paid most of September and part of October, so the net bill looked like $0 before Oct 1 and small after. Credits are a one-time offset, not a cost reduction. Raw pulls are kept on the Mac mini under /tmp/cistudy for this session. Timeline of the changes themselves: CI/CD architecture, CI rethink.

PropFlow Docs