GitHub Actions が遅いときの高速化:キャッシュから順に効く 6 つの手(2026 年 11 月)
目次
GitHub Actions が遅い理由は 2 つです。ジョブのたびに新しい VM が用意され、依存関係のダウンロードも Docker のビルドも最初からやり直すこと。そして、プライベートリポジトリの ubuntu-latest が 2 コアであること(GitHub のドキュメント、2026 年 11 月 11 日に確認)。直す順番は、時間を読む、キャッシュする、並列にする、コアを増やすかディスクを残す、です。
Skipbox は、Convika と同じ株式会社 Fluxenic が作っています。ジョブのあともディスクが残る GitHub Actions のランナーで、この記事の手の 1 つは自分たちの製品です。GitHub、Docker、Playwright の記載は、それぞれのドキュメントから引用しました。どれも 2026 年 11 月 11 日に読み、出典にリンクを並べています。
6 つの手と、それぞれがなくすもの
| 順番 | 手 | なくなるもの | 代わりにかかるもの |
|---|---|---|---|
| 1 | ステップごとの時間を読む | 当てずっぽう | なし |
| 2 | 依存関係をキャッシュする | レジストリからのダウンロード(キャッシュが当たったとき) | ジョブごとの復元と保存。GitHub のキャッシュは 1 リポジトリ 10 GB まで、7 日使われないと消える |
| 3 | Docker のレイヤーをキャッシュする | 変わっていないレイヤーの作り直し | ネットワーク越しの書き出しと読み込み。同じ 10 GB の中 |
| 4 | 並列にする、テストを分割する | 長いジョブ 1 本を待つ時間 | 課金される分数が増える。ジョブごとに準備をやり直し、分に切り上げられる |
| 5 | GitHub の大きいランナーにする | CPU を使い切るステップの遅さ | 高い単価。4 コアは 1 分 $0.012、8 コアは $0.022、16 コアは $0.042 |
| 6 | ジョブのあともディスクが残るランナーにする:Skipbox(このサイトを運営する株式会社 Fluxenic 製) | ダウンロードと作り直しそのもの。Docker のレイヤー、パッケージのキャッシュ、ツールキャッシュが VM に残っている | 定額。4・8・16 vCPU が月 6,000 円・12,000 円・23,000 円(税込)で、実行時間は無制限 |
手の 1〜4 は、いまのランナーのままできます。先にやるのはこちらです。
1. どのステップが遅いかを読む
実行を開き、ジョブを選ぶと、ステップごとに時間が出ます。GitHub のドキュメントに "You can see the time it took for each step to run." とあります。
いつもの実行を 1 つ選び、時間の長い順に並べて、何を待っているのかを分けます。
| 遅いステップ | 待っているもの | 効く手 |
|---|---|---|
| Node、Python、Java のセットアップ | ツールのダウンロード | 6(ツールキャッシュが残るランナー) |
| 依存関係のインストール | レジストリからのダウンロード | 2 |
docker build | レイヤーの作り直し | 3 か 6 |
| コンパイル、バンドル | CPU | 5 か 6 |
| テスト | CPU、または 1 列に並んだテストファイル | 4、次に 5 |
| ジョブの最後のキャッシュ保存 | キャッシュのアップロード | 6 |
コマンドを 5 つ並べたステップは、時間が 1 つしか出ません。5 つのステップに分けるか、各コマンドの前に time をつけます。
全体の形も見ます。3 分のジョブが 10 本あっても、14 分のジョブを 1 本待っているなら、パイプラインは 14 分です。
2. 依存関係をキャッシュする
GitHub ホストランナーのジョブは、毎回パッケージをダウンロードし直します。GitHub の setup アクションなら、入力を 1 つ足すだけでキャッシュできます。
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v7
with:
node-version: 24
cache: "npm"
- run: npm ci
パッケージマネージャーごとのアクションは、GitHub のキャッシュのリファレンスに載っています。
| パッケージマネージャー | アクション |
|---|---|
| npm、Yarn、pnpm | actions/setup-node |
| pip、pipenv、Poetry | actions/setup-python |
| Gradle、Maven | actions/setup-java |
| RubyGems | ruby/setup-ruby |
| Go | actions/setup-go |
| .NET NuGet | actions/setup-dotnet |
キャッシュが効かないときに見る、GitHub の決まり
「キャッシュを入れたのに速くならない」ときは、たいてい次のどれかです。どれも GitHub のドキュメントの記載です。
- 7 日使われないと消える:"GitHub will remove any cache entries that have not been accessed in over 7 days."
- 1 リポジトリ 10 GB まで:"By default, the limit is 10 GB per repository." 超えると "the cache eviction policy will create space by deleting the caches in order of last access date, from oldest to most recent."、つまり最後に使われた日が古いものから消えます。
- 作っては消える:"The cache eviction process may cause cache thrashing, where caches are created and deleted at a high frequency." 上限に近いリポジトリでは、保存したキャッシュがすぐ消されます。
- ブランチをまたげない:"Workflow runs cannot restore caches created for child branches or sibling branches." 新しいブランチが使えるのは、デフォルトブランチが保存したキャッシュだけです。
- プルリクエストのキャッシュは、そのプルリクエストだけ:プルリクエストの実行が保存したキャッシュは "can only be restored by re-runs of the pull request" です。
当たっても、時間はかかります。ランナーは毎回新しい VM なので、ジョブのたびにキャッシュをダウンロードして展開し、キーが変われば保存し直します。
3. Docker のレイヤーをキャッシュする
新しい VM にはレイヤーがないので、docker build はすべての命令を実行し直します。Docker のビルド用アクションは、レイヤーを GitHub のキャッシュに置けます。
- name: Build and push
uses: docker/build-push-action@v7
with:
context: .
push: true
tags: "<registry>/<image>:latest"
cache-from: type=gha
cache-to: type=gha,mode=max
Docker のドキュメントは、このバックエンドを "the recommended cache to use inside your GitHub Actions workflows, as long as your use case falls within the size and usage limits set by GitHub" と書いています。上限は 2 と同じ 10 GB と 7 日で、依存関係のキャッシュと分け合います。
当たるかどうかを決める設定は 2 つです。
mode=max:"Inmincache mode (the default), only layers that are exported into the resulting image are cached, while inmaxcache mode, all layers are cached, even those of intermediate steps." 既定のminでは、途中のステージのレイヤーが保存されません。マルチステージビルドにはmaxが要ります。scope:"By default, it is set tobuildkit. If you build multiple images, each build will overwrite the cache of the previous, leaving only the final cache." イメージが複数あるなら、イメージごとにscopeを分けます。
Dockerfile の順番は、どの設定よりも効きます。ロックファイルをコピーして依存関係を入れてから、ソースをコピーします。ソースだけが変わったとき、依存関係のレイヤーをそのまま使えます。
4. 並列にする、テストを分割する
GitHub のワークフローの文法では、ジョブは "run in parallel by default"、つまり何も書かなければ並列に動きます。lint、型チェック、単体テスト、ビルドを 4 つのジョブに分ければ、いちばん長いジョブの時間で終わります。
長いテストは、マトリックスで分割(シャーディング)します。Playwright のドキュメントに "To shard the test suite, pass --shard=x/y to the command line." とあります。
jobs:
e2e:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v7
with:
node-version: 24
cache: "npm"
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
新しい push で要らなくなった実行は、止めます。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
分割には、かかるものがあります。
- 準備をやり直す:分割したジョブはそれぞれ、チェックアウトし、キャッシュを復元し、ブラウザーを入れ直します。12 分のテストを 4 つに分けると、1 つ 3 分に、その準備の時間が足されます。
- 課金される分数が増える:GitHub の料金表に "GitHub rounds the minutes and partial minutes each job uses up to the nearest whole minute." とあります。ジョブごとに、分に切り上げられます。
- 同時に動かせる数はプランで決まる:標準の GitHub ホストランナーが同時に動かせるジョブは、GitHub Free で 20、Pro で 40、Team で 60、Enterprise で 500 です。
分割は、分数を払って待ち時間を買う手です。分単位の料金のランナーでは、その分が請求に乗ります。
5. GitHub の大きいランナーにする
ここまで削って残るのは本当の仕事で、その多くは CPU です。コンパイル、バンドル、テストのワーカー。GitHub で Linux x64 のジョブに割り当てられるものは次のとおりです(2026 年 11 月 11 日に確認)。
| ランナー | CPU | メモリー | ディスク | 1 分の単価 |
|---|---|---|---|---|
ubuntu-latest(プライベートリポジトリ) | 2 | 8 GB | 14 GB | $0.006 |
ubuntu-latest(パブリックリポジトリ) | 4 | 16 GB | 14 GB | 無料 |
| 大きいランナー、4 コア | 4 | 16 GB | 150 GB | $0.012 |
| 大きいランナー、8 コア | 8 | 32 GB | 300 GB | $0.022 |
| 大きいランナー、16 コア | 16 | 64 GB | 600 GB | $0.042 |
条件が 2 つあります。"Larger runners are only available for organizations and enterprises using the GitHub Team or GitHub Enterprise Cloud plans."、つまり GitHub Team か Enterprise Cloud の組織だけが使えます。そして "Larger runners are not free for public repositories."、パブリックリポジトリでも料金がかかります。
増えたコアは、ジョブが使わなければ意味がありません。
- run: make -j"$(nproc)"
ネットワークを待つステップは、コアを増やしても速くなりません。大きいランナーも、ジョブのたびに新しい VM です。npm ci も docker pull も、これまでどおりダウンロードします。
6. ジョブのあともディスクが残るランナーにする
2 と 3 は、「ジョブが始まるとき、ランナーのディスクは空」という 1 つの事実への対処です。ディスクが残るランナーなら、対処そのものが要りません。なくなっていないものは、復元しなくて済みます。
GitHub のドキュメントは、セルフホストランナーについて "Don't need to have a clean instance for every job execution."(ジョブごとにまっさらなマシンは要らない)と書いています。自分で立てることもできますが、マシンも、更新も、掃除も自分の仕事になります。中身はセルフホストランナーの構築と運用にかかるコストにまとめました。
Skipbox は、その運用を任せられるランナーです。アカウントごとに専用の Linux x64 の VM があり、ジョブのあとも残ります。
- ディスクに残るもの:Docker のイメージ・レイヤー・ビルドキャッシュ。npm・pip・Go・Gradle・Cargo などのキャッシュ。setup-* のアクションが入れるツールキャッシュ。
- ジョブごとに消すもの:ランナーの認証情報、チェックアウトしたコードがある作業ディレクトリ、すべてのコンテナー、
~/.npmrcなどの認証ファイル。 - 7 日の決まりも、ブランチの決まりもない:キャッシュは GitHub の 10 GB の中ではなく、VM のディスクの上のファイルです。ディスクは、いちばん小さいプランで 80 GB あります。
- コアが増える:
runs-on: skipboxのジョブは 4 vCPU・8 GB。大きいプランなら、skipbox-8x16とskipbox-16x32で 8 vCPU と 16 vCPU を選べます。 - 定額:月 6,000 円・12,000 円・23,000 円(税込)で、実行時間は無制限。テストを分割しても、やり直しても、請求は増えません。
Docker には注意が 1 つあります。docker build と docker compose build は、VM に残ったレイヤーを使います。docker/setup-buildx-action の既定のビルダーはジョブごとに空で始まるので、driver: docker を指定して VM のキャッシュを使います。
自分のジョブで測る
Skipbox の速さを測った結果は、まだ公開していません。そのため、この記事では Skipbox の速さの数字を出しません。確実なのは、自分のジョブで測ることです。同じコミットで、2 回目以降の実行を、ステップごとの時間で両方のランナーについて並べます。
料金
GitHub は料金をドルで請求するので、比べるときは Skipbox のドルの料金(月 $39・$79・$149)で計算します。Skipbox の M(8 vCPU、月 $79)は、月 $18 を含む GitHub Team で GitHub の 8 コア(1 分 $0.022)を使う場合と比べて、月 4,410 分を超えると安くなります。式は ($79 + $18) ÷ $0.022 です。S は 4 コアに対して月 4,750 分、L は 16 コアに対して月 3,977 分を超えたところです。
macOS、Windows、Arm のジョブは Skipbox では動きません。外部のサービスの応答を待つステップは、どのランナーでも同じ速さです。
試すには、ジョブを 1 つ選び、runs-on: を skipbox に書き換えて push します。Skipbox のトライアルは、4 vCPU のジョブを 1 本ずつ、最初のジョブから 7 日間か 3,000 分のどちらか早いほうまで無料で、カードは要りません。
Skipbox の無料トライアルを始める(skipbox.dev)
月額固定のランナーの一覧は GitHub Actions のランナーを月額固定で使えるサービス一覧、各社の 1 分あたりの単価は GitHub Actions の料金と高速ランナーの費用比較にあります。自分のランナーに GitHub の料金がかかるかどうかは、セルフホストランナーは有料? 料金は無料ですをどうぞ。
あわせて読む
- GitHub Actions の料金(2026 年 11 月):1 分の単価、プランの無料枠、1 か月の計算
- Blacksmith の料金と代替サービス:課金の方式で比較
- AI エージェントで PR が増えたときの CI の分数と対策
- 予算・使用上限でジョブが開始されないときの直し方
よくある質問
GitHub Actions を高速化するには、何からやればいいですか?
次の順番です。ステップごとの時間を読んで遅いステップを見つける。setup アクションの cache で依存関係をキャッシュする。cache-to: type=gha,mode=max で Docker のレイヤーをキャッシュする。--shard でテストを並列のジョブに分ける。CPU を使い切るステップにコアを足す。ジョブのあともディスクが残るランナーなら、ダウンロードそのものがなくなります。Skipbox はその 1 つで、料金は月額の定額です。Skipbox は、Convika と同じ株式会社 Fluxenic が作っています。
GitHub Actions はなぜ遅いのですか?
理由は 2 つです。GitHub ホストランナーは、GitHub の説明では "a new virtual machine"、つまりジョブごとに新しい VM です。ツールと依存関係を毎回ダウンロードし、Docker のイメージも前回のレイヤーなしでビルドします。もう 1 つはコアの数で、プライベートリポジトリの ubuntu-latest は 2 コア・8 GB(2026 年 11 月 11 日に確認)。パブリックリポジトリの 4 コア・16 GB の半分です。
キャッシュを入れたのに速くならないのは、なぜですか?
キャッシュが当たっていないか、当たっても復元に時間がかかっているかです。GitHub のキャッシュは、7 日使われないと消え、1 リポジトリ 10 GB を超えると古いものから消え、兄弟のブランチとは共有されません。新しいブランチは、キャッシュなしで始まることがよくあります。当たったときも、ランナーは毎回新しい VM なので、キャッシュのダウンロードと展開はジョブのたびに走ります。
Docker のレイヤーがジョブのあとも残るランナーはありますか?
あります。Skipbox はアカウントごとに専用の VM を用意し、ジョブのあとも残します。Docker のイメージ・レイヤー・ビルドキャッシュ、パッケージのキャッシュ、ツールキャッシュは、次のジョブが始まるときにはディスクにあります。料金は 4・8・16 vCPU が月 6,000 円・12,000 円・23,000 円(税込)の定額で、実行時間は無制限。動かせるのはパブリックリポジトリとプライベートリポジトリの Linux x64 のジョブで、書き換えるのは runs-on: skipbox の一行です。自分で運用するセルフホストランナーでも、ディスクは残ります。
大きいランナーにすれば速くなりますか?
CPU を使い切るステップは速くなります。コンパイラー、バンドラー、テストのワーカーは、割り当てられたコアを使うからです。GitHub の大きい Linux のランナーは、4 コアが 1 分 $0.012、8 コアが $0.022、16 コアが $0.042 です(2026 年 11 月 11 日に確認)。ネットワークを待つステップは変わりません。大きいランナーも、ジョブのたびに新しい VM です。
テストを分割すると、料金は増えますか?
課金される分数は増えます。分割したジョブはそれぞれチェックアウトとインストールをやり直し、GitHub はジョブごとに分に切り上げます("GitHub rounds the minutes and partial minutes each job uses up to the nearest whole minute.")。分数を払って待ち時間を短くする手です。定額のランナーなら、分割しても請求は変わりません。
出典(2026 年 11 月 11 日、日本時間に読んだもの)
- GitHub「Using workflow run logs」:ステップごとの時間(2026 年 11 月 11 日に読んだもの)
- GitHub「Dependency caching reference」:setup アクション、7 日、10 GB と消える順番、ブランチとプルリクエストの範囲(2026 年 11 月 11 日に読んだもの)
- actions/setup-node:
cacheの入力(2026 年 11 月 11 日に読んだもの) - Docker「GitHub Actions cache」「Cache storage backends」:
type=gha、scope、minとmax、ワークフローの例(2026 年 11 月 11 日に読んだもの) - GitHub「Workflow syntax」「Control the concurrency of workflows and jobs」:ジョブは既定で並列、
cancel-in-progress(2026 年 11 月 11 日に読んだもの) - Playwright「Sharding」:
--shardとマトリックス(2026 年 11 月 11 日に読んだもの) - GitHub「Actions limits」:プランごとの同時に動かせるジョブの数(2026 年 11 月 11 日に読んだもの)
- GitHub「GitHub-hosted runners reference」「Larger runners reference」「Actions runner pricing」:ランナーの大きさ、1 分の単価、分への切り上げ(2026 年 11 月 11 日に読んだもの)
- GitHub「Self-hosted runners」「GitHub Actions billing」(2026 年 11 月 11 日に読んだもの)
- Skipbox:ジョブのあとも残るものと消すもの、80 GB のディスク、大きさとラベル、buildx の注意、プラン、トライアル(2026 年 11 月 11 日に読んだもの)
関連記事
- AI エージェントで PR が増えて CI が遅い・高い:GitHub Actions の分数の計算と対策(Copilot コードレビューの分数も)AI エージェントがプルリクエストを次々に開くと、push のたびに CI が走り、GitHub Actions の待ち時間と請求が増えます。1 日 10・30・100 PR での分数と請求の計算、cancel-in-progress やパスのフィルター、larger runner、月額固定のランナーという対策、Copilot のコードレビューが使う Actions の分数をまとめました(2026 年 11 月 11 日に確認)。
- GitHub Actions のセルフホストランナーは有料? 料金は無料です(2026 年 11 月)GitHub Actions のセルフホストランナーに、GitHub の料金はかかりません(GitHub の課金のドキュメント、2026 年 11 月 11 日に確認)。2025 年 12 月に発表された課金は翌日に見送り。AI が「有料」と答える理由、よくある 2 つの取り違え、代わりにかかるマシン代と運用の手間をまとめました。
- Blacksmith の料金と代替サービス:GitHub Actions のランナーを課金の方式で比較(2026 年 11 月)Blacksmith の料金を料金ページの記載のまま整理し、代わりになる GitHub Actions のランナーを課金の方式(分単位、分数つきの月額プラン、自分のクラウドに置くライセンス、サーバー 1 台ごとの定額、運営も任せる定額)で 1 つの表に並べました。無料枠を超えたあとの請求の実例と、定額の Skipbox・OpenRelay との分岐点の計算つきです(2026 年 11 月 11 日に確認)。