コンテンツへスキップ
LatchkeyLatchkey home

より速いCIのための依存関係cache戦略

最大で最も安価なCIの高速化は、実行ごとに同じ依存関係を再ダウンロードしないことだ。package storeをcacheし、lockfileでkey化すれば、ほとんどのインストールがほぼ瞬時になる。

依存関係のインストールは多くのCIのjobを占める。良いcache戦略は前の実行からpackage storeを復元し、インストーラが実際に変わったものだけを取得するようにする - 数分を数秒に変える。

プロジェクトではなくstoreをcacheする

node_modulesのようなプロジェクトディレクトリよりも、パッケージマネージャのグローバルstoreやdownload cache(npm cache、~/.m2、pip wheel cache、Cargo registry)をcacheするほうがよい。storeはポータブルで、copyされたファイルを盲信するのではなく、インストーラに速く検証済みのインストールをさせられる。

lockfileでkey化する

cache keyは、依存関係が変わったときちょうど変わるべきだ - lockfile(package-lock.jsonpoetry.lockCargo.lock)のhash。同じlockfile → 同じcache → 完全hit。変わったlockfile → 新しいcacheエントリ、そしてrestore-keyのfallbackが前のstoreの大部分を回復する。

Lockfile-keyed cache
key: deps-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
  deps-${{ runner.os }}-

よくある落とし穴

  • 常に変わる値でkey化する → hit率0%。
  • node_modulesを直接cacheし、lockfileのdriftを隠す。
  • keyにOS/archを含めない → 互換性のないバイナリを復元する。
  • 無効化より速くcacheし、古い推移的depsを提供する。

見返りを測る

cache hitとcold実行でインストール時間を比べる; 似ているなら、cacheはhitしていない。健全な依存関係cacheは、数分のインストールを数秒に変えるべきで、hit率はlockfileに触れないbranchで高いはずだ。

重要なポイント

  • 解決済みのプロジェクトディレクトリではなく、package store/download cacheをcacheする。
  • lockfileのhashでkey化する; ニアミスのfallbackにrestore-keysを使う。
  • 互換性のないバイナリを復元しないよう、OS/archを含める。
  • hit vs coldのインストール時間を比べて検証する - 似ているならhitしていない。

よくある質問

What is Dependency caching strategies for faster CI?
Dependency installation dominates many CI jobs. A good caching strategy restores the package store from a previous run so the installer only fetches what actually changed - turning minutes into seconds.
Cache the store, not the project?
Prefer caching the package manager’s global store or download cache (npm cache, ~/.m2, pip wheel cache, Cargo registry) over a project directory like node_modules. The store is portable and lets the installer do a fast, validated install rather than blindly trusting copied files.
Key on the lockfile?
The cache key should change exactly when dependencies change - a hash of the lockfile (package-lock.json, poetry.lock, Cargo.lock). Same lockfile → same cache → full hit. Changed lockfile → new cache entry, and a restore-key fallback recovers most of the previous store.
Measure the payoff?
Compare install time on a cache hit vs a cold run; if they are similar, the cache is not hitting. A healthy dependency cache should turn a multi-minute install into seconds, and the hit rate should be high on branches that do not touch the lockfile.

関連ガイド