CI Cost Analysis — Six Months of Actual Numbers

We thought we'd save $48k a year by going self-hosted. We saved $11k. Here's where the other $37k went.

John Baek
John Baek
Founder, CollabOps
CI Cost Analysis — Six Months of Actual Numbers

Last fall a customer CTO walked into our office holding a GitHub Actions invoice.

"$4,000 a month. We could replace this with four $200 EC2 boxes. Forty-eight grand a year saved."

Six months later we measured the actual saving: $11,000. Where the other $37,000 went is what this post is about.

The first table (the one they brought)

GitHub Actions:                $4,000 / mo  →  $48,000 / yr
Self-hosted (ec2 c5.2xlarge × 4):
  EC2:                         $560 / mo
  Network:                     $50 / mo
  Storage:                     $40 / mo
  total:                       $650 / mo  →  $7,800 / yr

Annual savings:                            $40,200 (84%)

Clean. So we started the migration.

Six months later (measured)

Self-hosted direct cost:                  $7,800 / yr (as planned)

Missing line items:
  + Idle worker time (avg ~38% utilization):
      *Plan* assumed near-100% utilization
      4 EC2 instances actually needed 5× build-load capacity
      Actual EC2 cost:                    $9,800 / yr
  + Ops headcount (avg 12 hrs / month):
      ops engineer rate × 12h × 12mo      $14,400 / yr
  + Self-hosted secret store (Vault):
      server + license + backup           $2,800 / yr
  + Observability stack:
      Prometheus + Grafana self-hosted    $1,200 / yr
  + Security patches / OS upgrades:
      avg quarterly × 4 hrs               $1,920 / yr
  + Build worker OS license:
      one Windows worker                  $600 / yr
  + Immutable image pipeline ops:
      Packer + S3 + rotation              $400 / yr

Actual self-hosted total:                  $31,120 / yr  ⓐ

GitHub Actions scenario (assumed):
  $4,000 × 12                              $48,000 / yr  ⓑ

Real saving (ⓑ − ⓐ):                       $16,880 / yr

That's the clean arithmetic. We said $11,000. The remaining $5,880 came from somewhere else.

The last missing item — build queue time

For the first three months on self-hosted, build queue wait increased by an average of 17 minutes. Four workers wasn't enough; concurrent pushes formed a line. With 22 engineers each pushing twice a day:

22 × 2 pushes/day × 200 days × 17 min lost = 124,667 min
                                           = 2,078 hours
                                           = ~$5,900 (engineer rate)

This is the indirect cost. It doesn't appear on any invoice — and it's often the most expensive line item.

In month three we added two more workers. Queue time dropped to five minutes. From that point the savings became real. Six-month average saving: $11,000.

So is self-hosted not the answer?

It is. Just $11k of saving, not $48k. With it comes control — compliance, audit, data residency.

One thing worth naming: every line item above except the direct costs is the cost of DIY operations. Worker scaling, a secret store, an observability stack, patching — all handled by hand, because this customer assembled their runner infrastructure themselves. On a managed self-hosted platform those lines move onto the platform, and the math changes. We wrote that comparison up separately with 12 months of data.

A workload-shape decision matrix:

WorkloadRecommended
Under 5,000 build min/monthhosted (ops cost > saving)
5,000–50,000 build min/monthhosted, with hybrid options like spot workers
Over 50,000 build min/month, no compliance needDIY not recommended; managed self-hosted makes the math work (ops load moves to the platform)
Over 50,000 build min/month, with complianceself-hosted (control justifies it)
Air-gapped / data residency mandatedself-hosted (no choice)

The really expensive line

The most expensive line in this whole exercise wasn't idle workers, ops headcount, or queue time. It was the sunk cost of starting a decision on the wrong assumption. If at month six you realize "this wasn't the right call," those six months are the real cost.

The customer who started believing in $48k savings ended up with $11k savings plus compliance control — a more accurate revenue function — and chose to stay. The right outcome, but they would have spent less sunk cost getting there if the original number had been correct.

If you're an engineering lead weighing a move from GitHub Actions, CircleCI, or GitLab SaaS to self-hosted CI, how many of the eight line items above you've already costed out determines how accurate that decision will be. And once you've noticed that most of those items are operational labor, the next question is who carries it — people or a platform. Carried by people, the saving stops at $11k. Carried by a platform, the math changes.

Tags#cicd#cost-analysis#self-hosted#infrastructure#devops