If you searched for GitHub Actions macOS slow, iOS CI stuck, or macos-latest queued, you probably see:
- 5–10 extra minutes of queue before merge (worse during release weeks)
xcodebuild/pod installwith wild variance—same commit, 2–3× spread- Engineer sentiment: “CI feels like a lottery—I won’t merge Friday afternoon”
👉 This page is the overview: benchmark results and reading paths. Queue, build variance, cache, ROI, and architecture each have a dedicated article—jump to what you need.
- warm build P95:
macos-latest14:12 → dedicated Mac mini M4 6:05 (−57%) - Queue: average 4:20 → 0
- Variance σ: 3:20 → 1:55 (about −40%)
Below: benchmark summary and shadow quick start. Cache YAML, scoring models, and architecture checklists live in the linked topic articles.
- warm P95 14:12 → 6:05; σ −40%; queue eliminated
- Optimization order: queue → cold/warm split → cache → concurrency isolation → hardware
- Reproduce: Shadow quick start
If the team ships 20+ PRs/day and macOS CI queues often → read the ROI cluster article and fill the cost model. Under ~50 builds/month, macos-latest may still suffice.
Jump by symptom: queue → Why macos-latest queues · build variance → iOS CI builds feel slow · ROI → Buy vs rent · data → waterfall + benchmark.
1. Why is GitHub Actions macOS / iOS CI slow?
Teams get stuck in different places. This page stays at overview level—jump to the topic that matches your symptom:
| What you're searching | Typical symptom | Read |
|---|---|---|
| macos-latest queued / github actions macos slow | PR waits 4–8 extra minutes; worse during release weeks | Why macos-latest queues |
| xcodebuild slow / ios ci slow fix | Same commit: sometimes 4 min, sometimes 12 | iOS CI builds feel slow |
| cocoapods cache / deriveddata cache ci | pod install swings 3–6 minutes |
Pods/SPM/DerivedData cache guide |
| self-hosted runner roi / mac mini ci | Buy or rent a Mac mini? | Buy vs rent ROI |
| self-hosted architecture / multi runner | Multi-machine concurrency, fallback, labels | Self-hosted architecture |
If you only want “how much faster is a different runner?”, stay on this page: Benchmark and waterfall.
2. Benchmark results: how much self-hosted Mac mini M4 helps
8-person iOS team · CocoaPods · 25–40 PRs/day · no app code changes, runner swap only. warm build headline data:
| Metric | macos-latest | Mac mini M4 | Change |
|---|---|---|---|
| P50 | 11:38 | 5:22 | -54% |
| P95 | 14:12 | 6:05 | -57% |
| σ | 3:20 | 1:55 | -40% |
| max | 22:40 | 8:30 | -62% |
| Failure rate (14 days) | 8.0% | 3.2% | — |
Environment summary: 8-person iOS team · CocoaPods · 25–40 PRs/day · Xcode 16.2 aligned on both sides · Mac mini M4 16GB + 1TB data volume · 14-day 187-PR shadow dual-run. cold/warm split: build variance article; reproduction: Shadow quick start.
4:00–5:00 |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 52% 5:00–6:00 |■■■■■■■■■■■■■■■■■■ 28% 6:00–7:00 |■■■■■■ 10% P95 6:05 |■■■■■■■■■■■■■■
3. P95 time waterfall: 14:12 → 6:05 (−57%)
The shareable core chart—where 8m 07s of savings comes from:
macos-latest P95 ████████████████████████ 14:12
│
Queue removed −4:50 ████████████░░░░░░░░░░░░
cache/Pods −1:40 ████░░░░░░░░░░░░░░░░░░░░
xcodebuild −1:15 ███░░░░░░░░░░░░░░░░░░░░░
Sign/upload −0:20 █░░░░░░░░░░░░░░░░░░░░░░░
▼
self-hosted P95 ██████████ 6:05 (−57%)
Queue alone ≈ −4:50 → read queue topic. Cache ≈ −1:40 → read cache guide.
4. Pick the article for your problem
These topics follow a typical troubleshooting order—start with what hurts most:
Queue pain? → Why macos-latest queues (in preparation) → This page: benchmark + waterfall Build times all over the place? → iOS CI builds feel slow (published) → Pods/SPM/DerivedData cache guide (published) Deciding buy vs rent? → Shadow data on this page → Buy vs rent ROI (in preparation) → Cloud Mac plans / CI/CD FAQ Multi-runner setup or fallback? → Self-hosted architecture (in preparation)
5. Topic nav
Each article covers one concrete problem. This page holds the benchmark overview and links.
| Topic | Best for | Status |
|---|---|---|
| Why macos-latest queues | PRs stuck waiting in queue | In preparation |
| iOS CI builds feel slow | Same commit, 2–3× build time spread | Published |
| Speed up iOS CI: Pods/SPM/DerivedData cache | Copy YAML, tune cache keys | Published |
| Is a self-hosted runner worth it? | Buy vs rent Cloud Mac math | In preparation |
| Self-hosted Mac mini architecture | Multi-runner, labels, fallback | In preparation |
Published related articles: Mac mini M4 CI primer · Engineering-hours ROI · CI/CD FAQ
6. Shadow benchmark quick start
Minimum reproduction steps below. Full workflow and rollout checklist: architecture topic; cache YAML: cache guide.
- Copy
ios-ci.yml→ios-ci-shadow.yml; add a job withruns-on: [self-hosted, macos-m4-ios] - Dual-run every PR against
macos-latestwith the same commit SHA for 7–14 days - Record wall-clock P50/P95 and queue time; compute warm build P95 separately (definition in iOS CI Builds Feel Slow?)
- Compare failure rates, then read buy vs rent ROI
on:
pull_request:
branches: [main, release/*]
jobs:
ios-hosted:
runs-on: macos-latest
ios-shadow:
runs-on: [self-hosted, macos-m4-ios]
# same steps · same SHA
7. FAQ
How much faster can a GitHub Actions macOS self-hosted runner be than macos-latest?
This run: warm build P95 −57% (14:12→6:05), σ −40%. See Benchmark; reproduce via Shadow quick start.
Why do GitHub Actions macOS runners queue?
Shared hosted pool + high concurrency during release weeks. Queue time is not billed but counts toward wall-clock. Full breakdown → queue topic.
Are self-hosted runners less stable?
Depends on ops: disk watermarks, runner supervision, signing material. Compare failure rates during shadow; here 14-day failure rate 8.0% → 3.2%. Keeping macos-latest as fallback reduces perceived risk.
Is a Mac mini worth it as a CI runner?
Worth evaluating at 20+ PRs/day with worsening queues. Under ~50 builds/month, hosted may suffice. Scoring model and TCO → buy vs rent ROI.
What are the limits of GitHub macos-latest?
Shared queue, short-lived workspaces, unstable cache across jobs, concurrent I/O contention. Cannot pin DerivedData or eliminate queueing.
How do you optimize iOS CI P95?
Queue → cold/warm → cache → concurrency → hardware. Step-by-step: queue · build variance · cache guide.
How do you optimize CocoaPods cache?
Full YAML and key design → cache guide.
How long does migration take?
1–2 days prep + shadow 7–14 days + gradual rollout 3–5 days. Start shadow with tests only, then import signing.
8. Conclusion
After switching to self-hosted runners, warm P95 dropped from 14:12 to 6:05 with much tighter variance. This page shows the benchmark and waterfall; queue, build variance, cache, ROI, and architecture each have a dedicated article. Run a shadow dual-run with your own data before committing to dedicated hardware.
Confirm ROI, then order
Suggested path: Shadow dual-run → buy vs rent ROI → Rent Mac mini M4. Vuncloud offers dedicated M4 nodes (Xcode preinstalled, 1TB data volume, runner setup guide).