Self-Hosted CI/CD vs. Cloud Pipelines — The Math Most Teams Never Do
Self-Hosted CI/CD vs. Cloud Pipelines — The Math Most Teams Never Do
TL;DR: A Hetzner VPS at €40/month is ~75x cheaper per minute than GitHub Actions hosted runners. But Jenkins maintenance costs $15-30K/year in engineer time (20-40 hours/month). The real answer is somewhere in between. GitHub Actions slashed prices up to 39% in January 2026, then tried to charge $0.002/min for self-hosted runners — and reversed course within 24 hours after mass developer backlash. AWS CodeBuild’s hidden costs (CloudWatch, NAT Gateway, S3) can 15x your apparent build cost. CircleCI’s 2023 security breach forced every customer to rotate secrets. macOS runners on GitHub Actions cost one developer $2,273 in 17 days. The right answer depends on your build volume, team size, and how much you value your engineers’ time vs. your cloud bill.
Every developer team runs CI/CD. Few have actually calculated what it costs.
The pricing pages look simple: GitHub Actions charges $0.008/minute for Linux. AWS CodeBuild charges $0.005/minute. Google Cloud Build offers 2,500 free minutes. It feels like pocket change.
Then someone runs the numbers. A team of 15 developers pushing 3 times a day with 8-minute builds burns through 54,000 minutes per month. At GitHub Actions rates, that’s $324/month — or $3,888/year — just for Linux builds. Add macOS for mobile, Windows for cross-platform testing, and you’re looking at a five-figure annual bill for something that runs on a computer.
Meanwhile, a Hetzner dedicated server with 64 GB RAM and NVMe storage costs €40/month. That’s €480/year for unlimited builds with no per-minute metering.
So why isn’t everyone self-hosting? Because the math isn’t that simple. Let’s do it properly.
The Landscape: What Are We Comparing?
Before diving into numbers, let’s define the three approaches:
Fully managed cloud CI/CD — You pay per minute, per seat, or per credit. The provider handles infrastructure, scaling, and maintenance. Examples: GitHub Actions, GitLab SaaS, CircleCI, AWS CodeBuild, Google Cloud Build, Azure DevOps Pipelines, Bitbucket Pipelines.
Self-hosted on VPS/dedicated servers — You manage the build infrastructure yourself. The CI/CD software is free; you pay for servers. Examples: Jenkins, GitLab CI (self-hosted), Drone CI, Woodpecker CI, Forgejo Actions.
Hybrid — Cloud orchestration with self-hosted compute. You get the workflow engine from a managed provider but run builds on your own machines. Examples: Buildkite, GitHub Actions self-hosted runners, GitLab SaaS with self-managed runners, Actions Runner Controller (ARC) on Kubernetes.
Each has hidden costs the pricing page won’t show you.
Cloud CI/CD: What You Actually Pay
The Price Comparison Table
Here’s what every major platform charges as of February 2026:
| Platform | Linux (per min) | macOS (per min) | Windows (per min) | Free Tier |
|---|---|---|---|---|
| GitHub Actions (Jan 2026) | $0.006 | $0.062 | $0.010 | 2,000 min/month |
| AWS CodeBuild (general1.small) | $0.005 | N/A | N/A | 100 min/month |
| AWS CodeBuild (general1.medium) | $0.010 | N/A | $0.018 | — |
| Google Cloud Build (e2-medium) | $0.003 | N/A | N/A | 2,500 min/month |
| Azure DevOps (hosted) | $40/parallel job/month | — | $40/parallel job/month | 1 free parallel job (1,800 min) |
| GitLab SaaS (Premium) | $0.010/min overage | N/A | N/A | 400 min (Free), 10K min (Premium) |
| CircleCI (medium Linux) | $0.006 | Similar to macOS tier | $0.096 | 6,000 credits/month |
| Bitbucket Pipelines | $0.008 | N/A | N/A | 50 min/month |
Sources: GitHub Actions pricing, AWS CodeBuild pricing, Google Cloud Build pricing, GitLab pricing, CircleCI pricing.
GitHub Actions had a major price reduction on January 1, 2026 — up to 39% off across the board. Windows arm64 runners saw the steepest cuts. Before this, Linux 2-core was $0.008/min.
Google Cloud Build is the cheapest per-minute option at $0.003/min with the most generous free tier (2,500 minutes/month). But it also underwent a pricing restructure in November 2025, switching from 120 free minutes per day to 2,500 per month — more flexible, but actually a reduction from the old ~3,600 minutes/month equivalent.
Azure DevOps uses a different model entirely: you pay per parallel job ($40/month for hosted, $15/month for self-hosted) rather than per minute. For teams running many short builds sequentially, this can be cheaper. For teams needing lots of parallelism, it gets expensive fast.
The macOS Trap
If you build iOS or macOS apps, brace yourself. GitHub Actions charges $0.062/minute for macOS — more than 10x the Linux rate. Apple’s licensing restrictions and specialized hardware make this unavoidable across every platform.
One developer documented their macOS runner costs:
- 28,723 minutes in the billing period
- Minus 300 free minutes = 28,423 billable minutes
- 28,423 × $0.08 (pre-reduction rate) = $2,273.84 for 17 days
- Projected monthly: ~$4,167
Their solution: buying Mac Minis for self-hosting. Savings: $4,000+/month. The hardware paid for itself in under two months.
The Credit System Trap (CircleCI)
CircleCI uses a credit-based model that sounds flexible until you do the math. Credits are sold in packages of 25,000 for $15 ($0.0006 per credit). A medium Linux executor consumes 10 credits/minute, so:
- 10,000 build minutes/month = 100,000 credits = $60/month
- Add Docker Layer Caching at 200 credits per job: 500 jobs × 200 = 100,000 extra credits = $60/month more
- Windows builds consume 160-500 credits/minute — up to $18/hour
The credit system obscures the actual per-minute cost behind a layer of abstraction. And some resource classes are being retired in February 2026, forcing migration to potentially more expensive tiers.
The Hidden Costs That Blow Up Cloud Bills
The per-minute rate is just the beginning. Here’s what the pricing pages don’t emphasize.
AWS CodeBuild: The 15x Multiplier
A 2-minute build on CodeBuild’s general1.medium instance appears to cost $0.02. But according to AWS’s own optimization guide, the real cost includes:
| Component | Cost |
|---|---|
| CodeBuild (2 min × $0.01/min) | $0.02 |
| CloudWatch Logs | ~$0.02 |
| S3 artifact storage | ~$0.01 |
| NAT Gateway (1 GB data) | ~$0.045 |
| ECR image pull (500 MB) | ~$0.02 |
| CodePipeline (prorated daily) | ~$0.033 |
| Actual total | ~$0.15 |
That’s 7.5x the apparent build cost. For builds with heavier data transfer or VPC-attached workloads, the multiplier can reach 15x.
The biggest silent killer is NAT Gateway charges. If your builds run in a VPC without proper endpoints, every byte of traffic goes through the NAT Gateway at $0.045/hour plus $0.045/GB. VPC endpoints cost $0.01/hour — a fraction of the price — but you have to know to set them up.
GitHub Actions: Minute Rounding
GitHub Actions bills in whole minutes, rounding up. Run a job for 5 seconds? Billed for 1 minute. Run for 1 minute and 1 second? Billed for 2 minutes. As one developer noted in the GitHub Community discussion:
“Run for 5 seconds. Billed for 1 minute. Run for 1 minute 1 second. Billed for 2 minutes.”
For workflows with many short jobs (linting, formatting, type checking), this rounding inflates the real cost significantly compared to the theoretical per-minute rate.
Google Cloud Build: Regional Pricing
Google Cloud Build’s pricing varies by region. The $0.003/min rate applies to US regions. Elsewhere:
| Region | e2-medium rate | Premium over US |
|---|---|---|
| US (us-central1) | $0.003/min | — |
| London (europe-west2) | $0.00342/min | +14% |
| Sydney (australia-southeast1) | $0.00375/min | +25% |
| Tokyo (asia-northeast1) | $0.00384/min | +28% |
If your team is distributed or your compliance requirements dictate non-US regions, factor this in.
The $127K Cloud Bill Nobody Saw Coming
A startup with 23 developers and 50,000 active users woke up to a $127,000 monthly cloud bill — with CI/CD as a significant contributor. The root cause: no autoscaling limits, no cost monitoring alerts, and a CI/CD pipeline that “just ran” without anyone watching the meter.
“CI/CD runs pipelines, Infra scales automatically, Costs show up weeks later in a finance dashboard.”
The lesson: managed CI/CD services have no hard spending caps. Billing alerts notify you after the damage is done.
Self-Hosted CI/CD: The Hetzner Effect
On the other end of the spectrum, self-hosting your builds on VPS or dedicated servers offers radically different economics.
Raw Server Costs
| Provider | Server | Specs | Monthly Cost |
|---|---|---|---|
| Hetzner AX41-NVMe | Dedicated | Ryzen 5 3600, 64 GB RAM, 2× 512 GB NVMe | ~€40 |
| Hetzner Cloud CX22 | VPS | 2 vCPU, 4 GB RAM, 40 GB SSD | €3.49 |
| Hetzner Cloud CX32 | VPS | 4 vCPU, 8 GB RAM, 80 GB SSD | €6.49 |
| DigitalOcean | Droplet | 2 vCPU, 4 GB RAM, 80 GB SSD | $24 |
| OVH | VPS | 2 vCPU, 4 GB RAM, 80 GB SSD | ~€6 |
Sources: Hetzner AX41-NVMe, Hetzner Cloud pricing.
The Altinity team calculated that Hetzner is approximately 75x cheaper per minute than GitHub Actions hosted runners. Even accounting for the overhead of managing your own infrastructure, the raw compute economics are overwhelming.
One developer on Hacker News reported using a single AX41-NVMe (~€40/month) for all their CI/CD, with each runner running as a separate user account for isolation.
The Engineer Time Cost: Jenkins
But here’s where the math gets complicated. “Free” self-hosted CI/CD isn’t free.
Buildkite’s analysis of Jenkins costs lays out the hidden price:
- Maintenance time: 5-10 hours per week = 20-40 hours/month
- Annual engineer cost: $15,000-$30,000 per mid-level DevOps engineer
- Escalation risk: It’s “almost always the most senior, and most expensive, engineers” who end up troubleshooting Jenkins
- Plugin hell: Maintaining plugins, troubleshooting version conflicts, and addressing security vulnerabilities
- Cascading failures: A “simple” Jenkins update can set off a chain reaction that takes hours or a full day to untangle
According to industry surveys, some organizations end up allocating 3-4 engineers dedicated entirely to Jenkins management. At $100K+ per engineer, that’s $300-400K/year to maintain a “free” tool.
Modern Alternatives to Jenkins
Jenkins isn’t the only option for self-hosted CI/CD. Several modern alternatives offer better developer experience with less maintenance burden:
GitLab CI (self-hosted): Full CI/CD integrated with your Git platform. The Community Edition is free and includes CI/CD runners. More opinionated than Jenkins, which means less configuration but also less flexibility.
Woodpecker CI: A community fork of Drone CI, fully open source (Apache 2.0). Container-native, YAML-based configuration, and designed to be lightweight. Ideal for teams that want a modern CI/CD tool without the Jenkins overhead.
Forgejo Actions: The CI/CD system built into Forgejo (a soft fork of Gitea). Compatible with GitHub Actions workflow syntax, which means existing workflows can be reused with minimal changes. For teams wanting self-hosted GitHub Actions compatibility.
Drone CI: Container-first CI/CD with a simple YAML pipeline format. Lightweight, but the project’s future has been uncertain since Harness acquired it.
The maintenance cost for these modern tools is significantly lower than Jenkins — typically 2-5 hours per month instead of 20-40. But they still require infrastructure management, security patching, and someone who knows how to keep them running.
The GitHub Actions Self-Hosted Runner Fee Revolt
In December 2025, GitHub announced a decision that sparked one of the largest developer backlashes in recent memory.
What Happened
On December 16, 2025, GitHub revealed a new $0.002 per minute “cloud platform charge” for self-hosted runner usage in private repositories, effective March 1, 2026. The fee would cover GitHub’s “Actions control plane” — job orchestration, scheduling, and workflow automation.
The math was brutal for heavy users. At 50,000 minutes/month, that’s $100. At 100,000 minutes, $200. One user in the GitHub Community discussion calculated their impact:
“Just ran the numbers, and for us, that’s close to $3,500 a month extra on our GitHub bill.”
Their organization used 1.6 million Actions minutes in November — on their own hardware.
The Community Response
The backlash was immediate and fierce. Within the GitHub discussion thread, developers expressed outrage:
“Those minutes are MY processing time, some of which I already pay for on other services. If it takes MY machine 30 minutes to do a build, you’re going to charge me for that when it places no load on YOUR services?”
“The audacity to charge for self-hosted compute.”
The trust damage went deeper than the pricing itself:
“It’s good that you’re doing damage control after the backlash, but I think for most of us the trust is already broken. Especially since you considered it to be a good thing to introduce the pricing change without even checking with the community.”
The Reversal
Less than 24 hours later, on December 17, 2025, GitHub reversed course. They postponed the fee indefinitely, stating they would “take time to re-evaluate our approach” and acknowledged they “missed the mark with this change by not including more of you in our planning.”
The hosted runner price cuts (up to 39%) still went into effect on January 1, 2026. But the episode revealed something important: GitHub’s long-term strategy includes monetizing the orchestration layer, even for self-hosted compute. The fee was postponed, not cancelled. Teams building on self-hosted GitHub Actions runners should plan for this cost eventually arriving.
Several companies moved quickly to capitalize on the uncertainty. Blacksmith and Northflank published analyses positioning themselves as alternatives.
Security: The Trade-offs Nobody Talks About
Cost isn’t the only variable. Where your code builds has real security implications.
Shared Runner Risks
Cloud CI/CD platforms typically run your builds on shared infrastructure. GitHub Actions hosted runners are ephemeral VMs, but the underlying hardware is shared. This creates attack surface:
- Side-channel attacks: Shared hardware can theoretically leak data between tenants through CPU cache timing, speculative execution, or memory pressure patterns.
- Supply chain poisoning: Public Actions from the marketplace run in your workflow’s security context. A compromised action can exfiltrate secrets, modify build artifacts, or inject malicious code.
The tj-actions Supply Chain Attack (March 2025)
In March 2025, the widely-used tj-actions/changed-files GitHub Action was compromised (CVE-2025-30066). The attack modified the action to dump CI/CD secrets — including AWS keys, GitHub tokens, and npm tokens — to the workflow logs.
The impact was massive: 23,000+ repositories used this action. Any repository that ran the compromised version had its secrets potentially exposed in public build logs.
This wasn’t a theoretical risk. It happened, it affected real production credentials, and it demonstrated that the GitHub Actions marketplace is a supply chain attack vector.
The CircleCI Security Breach (January 2023)
In January 2023, CircleCI disclosed a major security incident. Malware on an employee’s laptop stole a session cookie, giving attackers access to CircleCI’s internal systems from December 16-22, 2022. The result:
- Every customer had to rotate all secrets stored in CircleCI
- Production environment variables, API keys, and deployment credentials were potentially compromised
- Third-party OAuth tokens had to be revoked and reissued
One customer’s review captured the impact:
“We were a bit startled because of the security issue they faced and we had to renew all of the secrets which was painful.”
This is the inherent risk of centralized CI/CD: when the provider is compromised, every customer is affected simultaneously.
Self-Hosted Security: Different Risks
Self-hosted CI/CD eliminates shared infrastructure risks but introduces others:
- You’re responsible for patching: Every CVE in your CI/CD software, its dependencies, and the underlying OS is your problem
- Network isolation: Your CI runners need access to your code repositories, artifact registries, and deployment targets. Misconfigured network rules can expose internal systems
- Secret management: You need to implement your own secret injection (HashiCorp Vault, AWS Secrets Manager, etc.) rather than relying on the platform’s built-in secret store
The trade-off is clear: cloud CI/CD trades control for convenience, and when the convenience layer fails, you have no recourse except rotating everything.
The Hybrid Middle Ground
For many teams, the answer isn’t pure cloud or pure self-hosted — it’s a combination.
Self-Hosted Runners on GitHub Actions
GitHub Actions supports self-hosted runners that connect to GitHub’s orchestration layer. You get the workflow syntax, marketplace integrations, and GitHub-native experience while running builds on your own hardware.
For Kubernetes environments, Actions Runner Controller (ARC) automatically scales runner pods based on workflow demand. Several tools also exist specifically for Hetzner Cloud:
- TestFlows GitHub Hetzner Runners: Autoscaling self-hosted runners on Hetzner Cloud
- hcloud-github-runner: On-demand runners that spin up Hetzner VMs per workflow run
The current cost: $0/month for the orchestration (the postponed $0.002/min fee hasn’t taken effect). You only pay for your compute infrastructure.
Buildkite: The Per-Seat Hybrid
Buildkite pioneered the hybrid model: cloud-based orchestration with an open-source agent you run on your own infrastructure. The pricing model is per seat, not per minute:
- Free plan: Limited features
- Pro: $15/user/month
- Enterprise: $35/user/month
For a team of 10, that’s $150/month regardless of how many builds you run. Compare that to GitHub Actions, where the same team running 50,000 minutes/month would pay $300+ in compute alone.
Buildkite’s open-source agent keeps your code and secrets on your own infrastructure — the cloud component only handles orchestration, scheduling, and the dashboard. This addresses both the cost and security concerns of fully managed platforms.
GitLab SaaS with Self-Managed Runners
GitLab’s SaaS offering allows you to connect self-managed runners while using the hosted GitLab platform. This lets teams on the Premium ($29/user/month) or Ultimate ($99/user/month) tiers run builds on their own infrastructure without consuming their included compute minutes.
The included minutes are generous — 10,000 for Premium, 50,000 for Ultimate — and additional minutes cost $0.01/min (purchased in 1,000-minute blocks at $10). For teams that occasionally spike beyond their allocation, self-managed runners handle the overflow without overage charges.
Vendor Lock-in: YAML Hell and the Portability Myth
Every CI/CD platform uses YAML for pipeline configuration. None of them use the same YAML.
The Portability Problem
Moving between platforms means rewriting every pipeline:
| Feature | GitHub Actions | GitLab CI | CircleCI | Azure DevOps |
|---|---|---|---|---|
| Config file | .github/workflows/*.yml | .gitlab-ci.yml | .circleci/config.yml | azure-pipelines.yml |
| Job syntax | jobs.<id>.steps | stages + jobs | jobs.<id>.steps | stages + jobs |
| Secrets | ${{ secrets.X }} | $X (CI variables) | Environment variables | $(X) |
| Caching | actions/cache@v4 | cache: keyword | restore_cache/save_cache | Cache@2 task |
| Matrix builds | strategy.matrix | parallel:matrix | matrix: under parameters | strategy.matrix |
| Reusable workflows | uses: ./.github/workflows/x.yml | include: | Orbs | Templates |
A team with 50 workflow files faces weeks of migration work to move between platforms. This creates effective lock-in even when there’s no technical barrier to leaving.
The Emerging Alternatives
Several tools are trying to solve the portability problem:
Dagger: Founded by Solomon Hykes (Docker creator) and backed by a $20 million Series A, Dagger lets you define CI/CD pipelines in your programming language (Go, Python, TypeScript) instead of YAML. Pipelines run as containers, so they work identically on any CI platform. In 2025, Dagger launched Dagger Cloud (free for individuals), achieved SOC2 certification, and introduced Dagger Shell for easier adoption.
Depot: A specialized service offering up to 40x faster Docker builds compared to generic CI providers, with 16 CPUs, 32 GB RAM, and 50 GB persistent NVMe cache by default. Not a full CI/CD replacement, but a drop-in substitute for docker build that can dramatically cut container build costs. In 2025, they expanded to cache Bazel, Go, Gradle, and Turborepo builds.
Earthly (⚠️ no longer actively maintained as of 2025): Combined Makefile and Dockerfile concepts for container-based builds. While innovative, its maintenance status makes it unsuitable for new adoption.
The most viable approach shares a philosophy: decouple the pipeline definition from the CI platform. Your build logic lives in code, and the CI platform is reduced to a thin trigger layer.
For teams worried about lock-in, Dagger is the most promising direction. A Dagger pipeline can run on GitHub Actions today and move to Buildkite tomorrow without rewriting the build logic — only the trigger configuration changes.
Decision Framework: When to Use What
Choose fully managed cloud CI/CD if…
- ✅ Your team is small (< 10 developers) and build volume is under 10,000 minutes/month
- ✅ You have no dedicated DevOps/platform engineering capacity
- ✅ You need macOS/Windows builds and don’t want to maintain specialized hardware
- ✅ Your builds are infrequent or spiky — pay-per-minute makes sense when utilization is low
- ✅ You value zero maintenance over cost optimization
Choose self-hosted CI/CD if…
- ✅ Your build volume exceeds 50,000 minutes/month consistently
- ✅ You have dedicated DevOps engineers who can maintain infrastructure
- ✅ You need air-gapped or compliance-restricted build environments
- ✅ Your builds require specialized hardware (GPUs, ARM, high-memory machines)
- ✅ You’re comfortable with modern tools (Woodpecker CI, Forgejo Actions, GitLab CI) that reduce Jenkins-era maintenance overhead
Choose hybrid if…
- ✅ You want GitHub/GitLab workflow syntax but need to control costs at scale
- ✅ You need security isolation — your code and secrets never leave your infrastructure
- ✅ You have mixed workloads — some builds need managed macOS runners, others run fine on cheap Linux VPS
- ✅ Your team is growing and you want a model that scales linearly (per-seat) rather than exponentially (per-minute)
- ✅ You want to hedge against platform pricing changes (like the GitHub self-hosted runner fee)
Avoid these mistakes…
- ❌ Choosing Jenkins because it’s “free” — the engineer time cost dwarfs any managed CI/CD bill for teams under 50 developers
- ❌ Ignoring hidden costs on AWS CodeBuild — budget for CloudWatch, NAT Gateway, S3, and ECR, not just build minutes
- ❌ Using macOS hosted runners for high-volume iOS builds — self-host Mac Minis or use a specialized provider
- ❌ Picking a platform because of free tier generosity — you’ll outgrow the free tier, and the paid rate matters more
- ❌ Assuming YAML portability — every platform’s YAML is different, and migration costs are real
Cost Scenarios: Real Numbers for Real Teams
Scenario 1: Startup (5 developers, light builds)
Profile: 5 devs, 3 pushes/day each, 4-minute average builds, 20 working days/month = 1,200 minutes/month.
| Option | Monthly Cost |
|---|---|
| GitHub Actions (Linux) | ~$0 (within 2,000 free minutes) |
| Google Cloud Build | ~$0 (within 2,500 free minutes) |
| GitLab Free | ~$0 (within 2,000 total minutes for 5 users) |
| Hetzner VPS (CX22) + Woodpecker CI | €3.49 (~$3.80) |
Verdict: Use the free tier of any cloud provider. Self-hosting makes no sense at this scale.
Scenario 2: Mid-size team (15 developers, moderate builds)
Profile: 15 devs, 3 pushes/day, 8-minute builds, 20 working days = 7,200 minutes/month. Plus 2,000 minutes/month of macOS builds for mobile.
| Option | Monthly Cost |
|---|---|
| GitHub Actions (Linux + macOS) | $31.20 (Linux) + $124 (macOS) = $155.20 |
| Google Cloud Build (Linux only) + GitHub macOS | $14.10 + $124 = $138.10 |
| Hetzner AX41 (Linux) + GitHub macOS | €40 + $124 = ~$167 |
| Hetzner AX41 (Linux) + Mac Mini (self-hosted macOS) | €40 + |
| Buildkite (15 users) + Hetzner AX41 | $225 + €40 = ~$268 |
Verdict: Cloud is competitive for Linux builds at this volume. The macOS builds drive the total cost. Self-hosting Mac Minis saves money if you’re willing to manage them.
Scenario 3: Scale team (50 developers, heavy builds)
Profile: 50 devs, 4 pushes/day, 10-minute builds, 22 working days = 44,000 minutes/month Linux + 10,000 minutes macOS + 5,000 minutes Windows.
| Option | Monthly Cost |
|---|---|
| GitHub Actions (all platforms) | $264 + $620 + $50 = $934 |
| AWS CodeBuild (with hidden costs ~3x) | |
| Hetzner dedicated × 3 + Mac Minis × 2 | €120 + |
| Buildkite (50 users) + self-hosted | $750 + |
Verdict: At this scale, self-hosted saves thousands per year. The Buildkite hybrid model keeps the developer experience premium while cutting compute costs. Pure cloud CI/CD becomes the most expensive option.
Pre-Migration Audit Checklist
Before changing your CI/CD setup, answer these questions:
1. What’s your actual build volume?
Check your current platform’s usage dashboard. Calculate total minutes per month broken down by OS (Linux/macOS/Windows). Multiply by the per-minute rate of your target platform, including overage costs.
2. What are your hidden costs?
For AWS: audit CloudWatch Logs, S3 artifact storage, NAT Gateway charges, and ECR image pulls. For GitHub Actions: check for minute rounding impact on short jobs. For CircleCI: calculate Docker Layer Caching credit consumption.
3. Who maintains your CI/CD today?
If the answer is “nobody, it just works,” that’s a managed service earning its keep. If it’s “our most senior engineer spends 10+ hours/month on it,” that’s a cost you should quantify.
4. What are your security requirements?
If you handle PII, financial data, or operate under compliance frameworks (SOC 2, HIPAA, PCI DSS), evaluate whether shared cloud runners meet your audit requirements. Self-hosted or hybrid may be mandated.
5. How portable are your pipelines?
Count your workflow files. Estimate the effort to rewrite them for a different platform. Consider Dagger or Earthly if portability is a priority.
6. What’s your growth trajectory?
Per-minute pricing scales linearly with headcount and push frequency. If you’re doubling team size in 12 months, model the cost at that scale, not today’s.
7. Can you set up cost alerts before migrating?
On AWS, use AWS Budgets. On GitHub, monitor your billing dashboard. On Google Cloud, set budget alerts. Do this before the first build runs, not after the first surprise bill.
Key Takeaways
-
Cloud CI/CD pricing is deceptively simple. The per-minute rate is the tip of the iceberg. NAT Gateways, CloudWatch Logs, Docker Layer Caching, minute rounding, and regional pricing multipliers can 3-15x your apparent cost.
-
Self-hosted CI/CD is deceptively cheap. A €40/month Hetzner server is 75x cheaper per minute than GitHub Actions. But Jenkins maintenance costs $15-30K/year in engineer time. Modern tools like Woodpecker CI and Forgejo Actions reduce this dramatically.
-
The hybrid model is the best-kept secret. Buildkite’s per-seat pricing ($15/user/month) with self-hosted agents, or GitHub Actions with self-hosted runners, gives you managed workflow orchestration with self-hosted compute economics.
-
macOS builds are the budget killer. At $0.062/minute on GitHub Actions, iOS/macOS builds can cost $4,000+/month at moderate scale. Self-hosting Mac Minis is almost always cheaper for consistent workloads.
-
GitHub’s self-hosted runner fee is postponed, not cancelled. The December 2025 episode showed that GitHub intends to monetize orchestration. Plan for this cost eventually arriving.
-
Security isn’t just a checkbox. The tj-actions supply chain attack (23,000+ repos affected) and CircleCI’s 2023 breach (every customer forced to rotate secrets) demonstrate that cloud CI/CD is a meaningful attack surface. Self-hosted eliminates shared-infrastructure risk but adds patching responsibility.
-
Vendor lock-in is real but solvable. Every platform’s YAML is different, but tools like Dagger decouple build logic from the CI platform, making future migrations feasible. Earthly pioneered this space but is no longer maintained — Dagger, backed by Docker’s creator, is the current frontrunner.
The right CI/CD setup isn’t about finding the cheapest option — it’s about understanding the total cost of ownership, including the costs that don’t show up on any pricing page.