プラットフォームチームの移行レビューで、経営層が必ず聞く一言:「GitHub Actions から自前 Mac ノードに替えたら、開発効率はどれだけ上がる?」——「ビルドが少し速くなった」程度では会議は終わりません。2026 年、iOS / Flutter / React Native 各チームと対照実験を行った結果、自前 Mac ノード(オフィスの Mac mini、ラックの裸金属、または Cloud Mac に Runner を載せる)へ移行後の最大の効果はコンパイル自体ではなく、キューと待ち時間の消滅でした。以下では再現可能な 4 指標、3 チームの実測対照表で「どれだけ上がるか」に答え、2 週間で実行できる移行チェックリストと ROI 概算を示します。
Quick Answer:効率はどれだけ上がる?
| 気になる点 | 托管 macOS runner(移行前) | 自前 Mac ノード(移行後) | 典型的な改善幅 |
|---|---|---|---|
| PR push から全緑まで(E2E) | 42–68 分 | 9–16 分 | 約 70%–80% 短縮 |
| キュー待ち(queue time) | 15–45 分/回 | 0–2 分 | ほぼゼロ |
| Archive 1 回 | 11–14 分 | 8–11 分 | 約 15%–25%(キャッシュ命中後) |
| リリース夜の TestFlight 版数 | 1–2 版 | 3–5 版 | スループット約 2–3 倍 |
| 開発者の週間受動待機 | 3–6 人時/人 | 0.5–1.2 人時/人 | 約 75% 削減 |
一言で言えば:開発効率の主因は「待ち」であり「コンパイラの高速化」ではない。自前ノードが希少な macOS プールを共有キューから切り離し、DerivedData を永続化して初めて上表の規模感が出ます。
先に計測する指標——「どれだけ上がったか」を語る前に
移行後に「あまり速くない」と感じるチームの多くは、GitHub Actions の Job duration だけを見て queue time や Slack で待っている時間を無視しています。移行前後それぞれ 2 週間、最低 4 種類を記録してください:
- キュー待ち:
job queuedからjob startedまでの秒数を P50 / P95 で報告 - PR フィードバックループ:最後の push から required checks が全緑になるまで
- リリースウィンドウのスループット:固定 4 時間内に TestFlight へ成功アップロードできた回数
- 受動待機人時:開発者アンケート「今日 CI を何分待ったか」または PR コメントのタイムスタンプから推定
取得方法:GitHub API で run_started_at と created_at の差分、または workflow に queue 秒数を artifact へ書き出す step を追加。ベースラインなしの移行は、後から経営層へ ROI を説明できません。
| 指標 | 取得方法 | 移行成功のシグナル |
|---|---|---|
| Queue P95 | Actions API / カスタム step | >20min から <3min へ |
| PR フィードバック P50 | PR イベントのタイムスタンプ | 50% 以上短縮 |
| キャッシュ命中率 | DerivedData ディレクトリ容量 + ビルドログ | <20% から >60% へ |
| 並列失敗率 | 同一マシン上の複数 Job 失敗比率 | ディレクトリ分離後 <2% |
3 チーム対照:移行前 vs 移行後
以下 3 組は実際の移行案件(チーム名匿名)から、同一リポジトリ・同一 Xcode メジャー・2 週間の平日サンプルで条件を揃えています。
ケース A:12 名 iOS チーム、単一 App + 拡張
移行前はすべて macos-14 托管 runner。移行後は M4 16GB Cloud Mac 2 台の self-hosted Runner、DerivedData はローカル NVMe にマウント。PR 平均 18 回/日。
| 指標 | 移行前 | 移行後 | 変化 |
|---|---|---|---|
| PR フィードバック P50 | 52 分 | 11 分 | −79% |
| Queue P95 | 38 分 | 0.8 分 | −98% |
| Archive 1 回 | 12.4 分 | 9.1 分 | −27% |
| リリース夜 TestFlight 版数 | 1.5 版/夜 | 4 版/夜 | +167% |
Tech Lead のコメント:「以前は 17 時 push して 18 半過ぎまでマージ可否が分からなかった。今は水を汲みに行って戻ったら緑になっている。」
ケース B:28 名 KMP + Android メイン、Mac は iOS シェル専用
移行前は macOS Job と Android Job が同じリリースウィンドウを奪い合い。移行後は常設 M4 Pro 1 台 + リリース週に burst Cloud Mac 2 台(リリース burst 運用参照)。
| 指標 | 移行前 | 移行後 | 変化 |
|---|---|---|---|
| 両端 PR 全緑 P50 | 71 分 | 24 分 | −66% |
| リリース週 Queue 合計/日 | 6.2 時間 | 0.4 時間 | −94% |
| 開発者週待機(アンケート平均) | 4.8 人時 | 1.1 人時 | −77% |
ケース C:8 名インディー、月 2 回リリース
反例:移行後ほとんど改善なし——PR が少なくキューも元々ほぼゼロ。自前機のキーチェーン保守だけが増えた。Archive は 10.2 分→9.4 分(−8%)のみ、Queue はもともと 0 に近い。「どれだけ上がるか」は負荷形状に強く依存し、大企業の数字をそのまま当てはめてはいけません。
効果の源泉:キュー・キャッシュ・並列
総待ち時間を分解すると、非エンジニアの意思決定者にも説明しやすくなります:
PR 総時間 ≈ キュー待ち + 環境準備 + コンパイル・テスト + 成果物アップロード
1. キュー(最大要因):GitHub 托管 macOS runner は共有プール。リリース週や Xcode メジャーアップ週は P95 キュー 30 分超も珍しくありません。自前ノード = 専有 executor で queue 項目はほぼ消えます。
2. コールドスタートとキャッシュ:托管 Job は終了と同時に破棄され、DerivedData・Pods・SwiftPM キャッシュは毎回リセット。自前機でホットディレクトリを永続ボリュームに載せると 2 回目以降は約 20% 短縮が一般的。詳細は self-hosted Runner キャッシュとディスク FAQ。
3. 並列:Mac 2–3 台で matrix Job を並列処理し、リリース夜の「串刺しキュー」を解消。同一マシンで複数 Job を走らせる場合はディレクトリ分離必須——さもないとランダム失敗が効率を食い尽くします。
| フェーズ | 托管 runner の典型比率 | 自前ノード移行後 |
|---|---|---|
| キュー | 45%–70% | <5% |
| 依存解凍 / インデックス | 15%–25% | 5%–10%(永続キャッシュあり) |
| 純コンパイル・テスト | 20%–35% | 15%–30% |
2 週間の移行パス:先に対照、後から本番切替
金曜夕方に一気に本番切替するのは非推奨。再現可能なペースは次のとおり:
- 1–2 日目:Actions から 2 週間分の queue / duration ベースラインをエクスポート。Cloud Mac 1 台(約 5 分開通)に Runner をインストール、
runs-on: [self-hosted, macos, canary]で手動トリガーのみ - 3–5 日目:
~/ci/DerivedDataと SwiftPM キャッシュを永続化。同一 main commit で A/B 各 5 回、P50 を記録 - 6–8 日目:Release / nightly workflow の 50% を自前 label へ。托管 runner は fallback として残す
- 9–10 日目:PR required checks をすべて自前へ。ディスク 80% 水位と成果物クリーンアップ cron を設定
- 11–14 日目:対照表で振り返り、経営層へ ROI 報告。常設 1 台か日次 burst レンタルかを決定
オーケストレーション層は GitHub Actions のまま——YAML、権限、environment protection は変更不要、runs-on だけ変更。企業 Mac CI リソースプール選定の「オーケストレーションと実行の分離」と同じ考え方です。
最小 Workflow 変更例
jobs:
ios-build:
# 移行前:runs-on: macos-14
ios-build:
runs-on: [self-hosted, macos, ios-pool]
steps:
- uses: actions/checkout@v4
- name: Log queue metrics
run: echo "QUEUE_SEC=${QUEUE_SEC:-0}" >> $GITHUB_STEP_SUMMARY
機械購入をまだ決めていない場合、日次レンタルの M4 Cloud Macで 2 週間対照すれば、「全員が 1 時間待つ」人件費より安いことが多いです。
ROI 概算:効率の帳簿は機械の帳簿を上回るか?
ケース A の数値で使える式(時給 blended $55、示意のみ):
- 12 名 × 週あたり 3.7 人時の待ち削減 ≈ 44 人時/月 ≈ $2,420/月 の相当产出(または PR 早期マージによるコンフリクト再作業削減)
- M4 16GB Cloud Mac 2 台の月額 ≈ $206($103/台 × 2、料金ページ準拠)
- プラットフォーム兼任運用 ≈ 4–8 人時/月(ディスク、証明書、Runner アップグレード)
粗算でも純益はプラス——ただし小チーム低頻度ビルド(ケース C)では合わない場合があります。自チームの queue P95 を式に代入して判断:
月次効果 ≈ 開発者数 × 週あたり待ち削減人時 × 4 × 時給 − 機械月額 − 運用人時 × 時給
リリース週は 3 台目を burst 追加し、平常時は解約——ピークのために通年課金しない。購入 vs レンタルの長期 TCO は Mac mini を買うか Cloud Mac を借りるか を参照。
移行すべきでないケース——移行のための移行を避ける
以下ではまず動かない、または 1 週間レンタルで検証のみを勧めます:
- 月間 macOS Job <30 回 かつ Queue P95 が常時 <5 分——改善の天井が低い(ケース C)
- Runner を on-call できる人がいない——キューよりディスク満杯の方が精神を削る
- セキュリティ要件で機械が自社 VPC 内必須——ネットワークと鍵管理を先に整える
- 移行したら GitHub Actions が不要になると思っている——オーケストレーション、監査、権限はプラットフォームに残す価値がある
移行は手段、目的は計測可能な待ち時間の削減。2 週間の対照で PR フィードバックが 30% 以上改善しなければ、先に workflow 最適化(Job 分割、Archive 頻度削減)を——Mac 3 台購入より先に。
FAQ
GitHub Actions から自前 Mac へ移行すると、開発効率はどれくらい上がる?
高頻度 iOS チームでは PR フィードバック約 70% 短縮、キューほぼゼロが一般的。純コンパイルは 15%–25% 程度。低頻度チームは一桁パーセントのみ——必ずベースラインを取ってください。
Mac 1 台追加で足りる?
10 名以内・直列リリースなら通常足ります。matrix テストや複数 App 並列なら 2 台以上と並列上限設定を推奨——キャッシュの互い踏みを防ぐため。
自前化後、Actions 請求はどれだけ下がる?
macOS 分課金は 60%–90% 削減が多い(移行 Job の割合による)。ただし機械レンタル・購入と運用が増える。総合は上記 ROI 式で見る。
Cloud Mac とオフィス Mac mini で効率差は?
同一チップ・同一メモリならコンパイル性能は近い。差はネットワーク RTT(依存取得・アップロード)と NVMe かどうか。コードホストと artifact リポジトリに近いノードを選ぶ。
移行は署名・公証に影響する?
魔法のように良くはなりませんが、環境が安定するとキーチェーンとプロビジョニングプロファイルのドリフトが減り、「CI だけ再現する」深夜対応が間接的に減ります。
効果が見えるまでどれくらい?
Runner 接続とキャッシュディレクトリ有効化後、最初の営業日から queue 指標に変化が出ます。PR フィードバックループは 2 週間分サンプルしてから報告を。
まとめと関連記事
GitHub Actions から自前 Mac ノードへ移行したときの開発効率向上は、曖昧な「かなり速くなった」ではなく——典型的 iOS チームでは PR フィードバック約 7 割短縮、リリーススループット 2 倍がよくある規模感で、大半はキュー消滅、次が永続キャッシュです。2 週間の対照実験、4 指標、ROI 式で経営層が理解できる数字を出せます。対照が弱ければ、先に workflow 最適化の方が Mac 購入より得です。