TL;DR
GitLab Premium SaaS lists at $29/user/month in 2026, and the break-even versus a self-hosted instance lands somewhere between 8 and 25 seats depending almost entirely on CI runner usage and whether you value your own ops time at $0 or $80/hr. Below ~10 active developers, SaaS almost always wins. Above ~40 seats with heavy CI, self-hosting on Hetzner can cut your bill by 70%+ — but only if you actually run the runners yourself instead of buying GitLab compute minutes.
Why this question is harder than it looks
Most "self-host vs SaaS" comparisons stop at seats × price versus VM cost. That's wrong by an order of magnitude for GitLab, because GitLab's real cost driver isn't the seat — it's the CI/CD compute. A single Rails monorepo with a 12-minute pipeline running on every push will burn through the 10,000 included CI minutes on Premium in about a week with three active developers. After that you're paying $10 per 1,000 additional minutes, and the meter doesn't stop.
So the real comparison has four moving parts:
- Seat license cost (the obvious one)
- CI runner compute (the hidden one — usually 2-5x the seat cost at scale)
- Storage: Git repos, LFS, artifacts, container registry, package registry
- Operational overhead: backups, upgrades, monitoring, the 2 a.m. page
Get any of these wrong and your spreadsheet lies to you. Let's price each one honestly.
The SaaS side: what $29/seat actually buys
GitLab.com Premium in 2026 is $29/user/month (annual) and includes:
- 10,000 CI/CD minutes/month on shared
saas-linux-small-amd64runners (1 vCPU, ~3.75 GB RAM) - 50 GB storage and 100 GB transfer per namespace
- Standard support, no on-call
Additional CI minutes are sold in blocks: roughly $10 per 1,000 minutes on the small runner. Larger runners (saas-linux-medium, saas-linux-large) consume minutes at 2x and 3x multipliers respectively. A medium runner pipeline that takes 10 wall-clock minutes therefore burns 20 included minutes.
A realistic SaaS bill for 20 developers
Assume 20 devs, each merging ~6 MRs/week, each MR triggering a 12-minute pipeline on a medium runner:
| Item | Calculation | Monthly cost |
|---|---|---|
| Seats | 20 × $29 | $580 |
| CI minutes used | 20 × 6 × 4.3 × 12 × 2 = 12,384 min | — |
| Included minutes | 10,000 | — |
| Overage | 2,384 min × $10/1,000 | $24 |
| Storage overage (assume modest) | ~20 GB extra | $12 |
| Total | ~$616/mo |
That's roughly $7,400/year. Reasonable. Now let's see what self-hosting costs to deliver the same throughput.
The self-hosted side: sizing the box honestly
GitLab's own reference architecture recommends 8 vCPU and 16 GB RAM minimum for up to 1,000 users when running Omnibus on a single node. In practice, a team of 20 with active CI pulls comfortably on:
- GitLab application server: 4 vCPU, 8 GB RAM, 80 GB SSD (Postgres, Redis, Gitaly, Puma, Sidekiq all co-located)
- CI runner host(s): separate VMs that scale with pipeline load
- Object storage: S3-compatible bucket for artifacts, LFS, registry, backups
Co-locating runners on the GitLab box is the classic mistake. A single noisy pipeline (docker build, large test matrix) will starve Gitaly and turn the UI into molasses. Always separate runners.
Provider pricing reference (2026 list)
| Provider | SKU | vCPU | RAM | Disk | Monthly |
|---|---|---|---|---|---|
| Hetzner | CX22 | 2 | 4 GB | 40 GB | €4.50 |
| Hetzner | CX42 | 8 | 16 GB | 160 GB | €17.00 |
| Hetzner | CCX23 (dedicated) | 4 | 16 GB | 80 GB | €27.50 |
| DigitalOcean | s-2vcpu-4gb | 2 | 4 GB | 80 GB | $24 |
| DigitalOcean | s-4vcpu-8gb | 4 | 8 GB | 160 GB | $48 |
| DigitalOcean | c-8 (CPU-optimized) | 8 | 16 GB | 100 GB | $168 |
| Linode | Nanode 1GB | 1 | 1 GB | 25 GB | $5 |
| Linode | Dedicated 8GB | 4 | 8 GB | 160 GB | $72 |
The Hetzner premium versus the US clouds is brutal — and it's the single biggest reason GitLab self-hosting tilts toward Europe. The osscostcalc calculator on this site lets you flip the provider toggle for the exact same workload spec and watch the bill change by 4-5x.
A self-hosted bill for 20 developers
Mirror the SaaS scenario: 20 devs, ~12,400 CI minutes/month of medium-tier work.
| Component | Hetzner | DigitalOcean | Linode |
|---|---|---|---|
| App server (CCX23 / c-4 / Dedicated 8GB) | €27.50 | $84 | $72 |
| Runner host (CX42 / s-4vcpu-8gb / Dedicated 8GB) | €17.00 | $48 | $72 |
| Object storage (~200 GB) | €1.00 + traffic | $5 (Spaces base) | $5 |
| Backup snapshots (20%) | €5.50 | ~$16 | ~$14 |
| Bandwidth | included generous | $0 within 1 TB | included |
| Subtotal infra | ~$153 | ~$163 |
Even on the priciest of the three, that's $163/mo of metal versus $616/mo of SaaS — a $5,400/year gap on infrastructure alone. But infrastructure isn't the whole story.
The hidden cost: your time
GitLab Omnibus is not Postgres. It bundles Rails, Puma, Sidekiq, Workhorse, Gitaly, Praefect, GitLab Pages, the container registry, Prometheus, Grafana, and depending on version, Mattermost. Upgrades have a strict version path (you cannot jump from 16.x to 17.4 in one shot). Major releases occasionally require background migrations that run for hours.
A realistic ops budget for a small self-hosted GitLab:
| Task | Frequency | Hours |
|---|---|---|
| Monthly patch upgrade | 12×/year | 1.0 |
| Major version upgrade with migration check | 4×/year | 3.0 |
| Backup verification (restore drill) | 4×/year | 2.0 |
| Disk/performance tuning, log rotation cleanup | ad hoc | 6.0/yr |
| Incident response (Gitaly stuck, runner OOM) | 3-5×/yr | 8.0/yr |
| Total | ~40 hours/year |
At a loaded rate of $80/hr that's $3,200/year in time cost. At $150/hr (senior SRE in a high-COL market) it's $6,000. This is the number people leave out of the spreadsheet, and it's the number that flips the answer.
The break-even formula
Here's the model you can plug into a spreadsheet:
Break-even seats N where:
SaaS(N) = Self(N)
SaaS(N) = N × $29
+ max(0, CI_minutes(N) − 10,000) × $0.01
Self(N) = Infra(N) // see provider table
+ Storage(N) × $/GB
+ Backup(N)
+ (Ops_hours × $/hour) / 12
+ Runner_VMs(N) × $/runner_VM
Where CI_minutes(N) ≈ N × MRs_per_dev_week × 4.3 × pipeline_min × runner_multiplier.
Plugging in real numbers (Hetzner, 30 hrs/yr ops, $80/hr)
| Seats | SaaS $/mo | Self-host $/mo (Hetzner) | Winner |
|---|---|---|---|
| 5 | $145 | ~$56 + $200 ops = $256 | SaaS |
| 10 | $290 | ~$56 + $200 ops = $256 | self-host (barely) |
| 20 | $616 | ~$80 + $200 ops = $280 | self-host |
| 50 | $1,540 | ~$180 + $250 ops = $430 | self-host (big) |
| 100 | $3,200+ | ~$350 + $300 ops = $650 | self-host (massive) |
The same table on DigitalOcean
| Seats | SaaS | Self-host DO | Winner |
|---|---|---|---|
| 5 | $145 | ~$153 + $200 = $353 | SaaS |
| 10 | $290 | ~$153 + $200 = $353 | SaaS |
| 20 | $616 | ~$180 + $200 = $380 | self-host |
| 50 | $1,540 | ~$400 + $250 = $650 | self-host |
The break-even on DigitalOcean shifts to roughly 15-18 seats, versus 8-10 seats on Hetzner. Linode lands between the two, closer to DO.
Things the formula doesn't capture (but should change your mind)
1. Egress and Docker layer caching
If your CI builds large container images and pushes them to a registry, SaaS makes that egress-free internally. Self-hosting means either eating egress charges (DO/Linode are generous up to 1 TB/Droplet; Hetzner is genuinely cheap at €1/TB beyond 20 TB included) or co-locating your registry with the runners. Plan for it.
2. Runner autoscaling
The cheap self-host math assumes a single always-on runner VM. If your CI load is spiky (overnight idle, daytime burst), a Docker Machine or Kubernetes-based autoscaler on Hetzner Cloud can drop average compute by another 40-60%. It also adds complexity worth ~10 more ops hours/year. Worth it above ~30 seats.
3. SAML/SSO and compliance
SAML SSO requires Premium on GitLab.com and on self-hosted. SOC 2 evidence collection is easier on SaaS because GitLab Inc. produces the reports. If you need ISO 27001 or HIPAA scope reduction, self-hosting in a region you control is sometimes the only path — at which point the cost question is moot.
4. Data gravity
A 3-year-old GitLab instance with 400 GB of LFS, 200 GB of container images, and 80 GB of artifacts is not trivial to migrate in either direction. Pick once, pick well. The cost of being wrong is a weekend, not a coffee.
When SaaS is just better
Be honest about these scenarios. Self-hosting is the wrong call if:
- You have fewer than 8 paying seats and no dedicated infra person
- Your CI is light (under ~3,000 minutes/month)
- You need 99.95% uptime SLA with money attached
- Your team is fully remote across 4+ time zones and on-call is hard
- You're a regulated entity that wants someone else to hold the SOC 2 report
When self-hosting is a no-brainer
- 20+ active developers with heavy CI (Rails test suites, Go monorepos, Android builds)
- A compliance regime that requires EU or in-country data residency, and your SaaS region doesn't offer it
- You already run Kubernetes or have a Hetzner footprint and the marginal ops cost is ~$0
- Your build matrix needs >4 vCPU or >8 GB RAM per job — SaaS large runners get expensive fast
Decision checklist
Run through this before you commit either way. If you answer "yes" to four or more of the self-host column, run the numbers in the osscostcalc comparison tool with your actual seat count and CI minutes — the answer will almost certainly favor a CX42 + dedicated runner in Falkenstein.
| Question | Lean SaaS if yes | Lean self-host if yes |
|---|---|---|
| Under 10 active seats? | ✓ | |
| Over 25 active seats? | ✓ | |
| CI minutes >15,000/month? | ✓ | |
| Need EU/regional data residency? | ✓ | |
| Zero dedicated ops capacity? | ✓ | |
| Already have a Hetzner/DO account and a Terraform setup? | ✓ | |
| Need 99.95% uptime with SLA credits? | ✓ | |
| Build images >2 GB or test matrices >8 jobs? | ✓ |
What to do this week
- Pull your actual CI minute usage from GitLab.com (Admin → Usage Quotas) for the last 3 months. Multiply by 1.3 for headroom.
- Count active committers in the last 90 days, not licensed seats. The gap is often 20%.
- Price a CX42 + CX22 runner pair on Hetzner and a
s-4vcpu-8gb+s-2vcpu-4gbon DigitalOcean. Add 30 hours/year of ops at your loaded rate. - If self-host wins by less than 30%, stay on SaaS — the margin won't survive your first painful upgrade. If it wins by 50%+, plan the migration for the next quiet quarter.
- Whichever you pick, write down the trigger that would make you reconsider (e.g., "if seats exceed 60 or CI exceeds 25k min/mo, revisit"). Decisions without exit criteria become folklore.
The honest answer to "self-host or SaaS" is rarely ideological. It's a function of three numbers: seats, CI minutes, and what an hour of your time is worth. Put those in the formula above, and the right answer will pick itself.