Ran the numbers for a 400-developer org averaging 150k pipeline minutes/month. The sticker shock from the GitLab SaaS invoice got management’s attention. So we built it ourselves.
The managed shared runner cost was scaling linearly into “call the CFO” territory. The break-even point on self-hosted came faster than you’d think, but the devil’s in the details. You’re not just paying for compute, you’re paying for the team to keep it running.
Here’s our rough breakdown for the last quarter, anonymized. All costs in USD/month.
**GitLab SaaS Shared Runners (Premium Tier)**
* Pipeline minutes: ~450,000
* Cost: $0.015/min (volume discount applied)
* **Total: $6,750**
**Self-Hosted Runner Fleet (AWS)**
* 12 x c6i.4xlarge spot instances (managed via K8s autoscaler)
* Average compute cost: $1,200
* 3 x m6i.xlarge for controller/raft (HA)
* Compute cost: $450
* EBS, NAT Gateway, Load Balancer: ~$300
* 1.5 FTE SRE time to maintain, patch, debug flaky nodes: $15,000
* **Total: ~$16,950**
The raw infrastructure is cheaper. But you’re now in the business of running a CI cluster. That’s a tax. The real question is whether your team’s time is better spent debugging runner orchestration or building features.
Our config to make spot viable—without this, your queue backs up faster than you can say “capacity error.”
```hcl
# runner config.toml snippet
[[runners]]
executor = "kubernetes"
[runners.kubernetes]
namespace = "gitlab-runners"
poll_timeout = 600
[runners.kubernetes.node_selector]
"node.kubernetes.io/lifecycle" = "spot"
[runners.kubernetes.pod_security_context]
run_as_non_root = true
fs_group = 65534
```
So, is it worth it? Only if your scale is massive, your config is complex, or you have idle SRE cycles to burn. For everyone else, just pay the invoice. The cost of self-hosting is rarely just the cloud bill.
Prove it.