CircleCIのworkspaceをcacheに切り替えてストレージ利用量を8GB節約する

CircleCIのworkspaceをcacheに切り替えてストレージ利用量を8GB節約する
この記事の操作
Markdownで見る

Chrome(最新版)のBuilt-in AIが必要です。

Chrome(最新版)のBuilt-in AIが必要です。

CircleCIを運用していると、ストレージ使用量の増加に悩まされることがあります。今回、あるNode.jsプロジェクトでストレージが圧迫されている状況を調査したところ、workspaceの不適切な使用が原因だとわかりました。設定を見直してcacheベースの実装に移行した結果、約8GBのストレージ削減に成功したため、その過程を共有します。

問題の発見

CircleCIのダッシュボードを確認したところ、ストレージ使用量が想定以上に増えていました。

詳しく調べると、workspaceの使用量が特に多くなっています。

設定ファイルを確認すると、.circleci/continue_config.yml で node_modules 全体を persist_to_workspace で保存する実装になっていました。

このコードでは、root に ~/project を指定し、paths に node_modules と package-lock.json を含めています。一見すると問題なさそうに見える実装ですが、workspaceの仕組みを理解すると、ストレージ効率の観点で改善の余地があるとわかります。

workspaceとcacheの違い

CircleCIには、ジョブ間でファイルを共有する仕組みとして workspace と cache の2つがあります。名前が似ているため混同しやすいのですが、保持期間と用途が大きく異なります。

workspace は同一workflow内のジョブ間でファイルを共有するための一時的なストレージです。重要なのは、デフォルトで15日間保持される点でしょう。ワークフロー終了後も即座に削除されず、15日間はストレージを占有し続けます。たとえば、ビルドジョブで作成したアーティファクトをテストジョブに渡す場合に使います。

一方、cache は異なるワークフロー実行間でファイルを再利用するための永続的なストレージです。package-lock.json のようなキーが同じであれば、同じキャッシュを再利用するため、ストレージ効率が高くなります。node_modules のような依存関係ファイルの保存に適しています。

この違いを理解すると、今回の問題が見えてきます。node_modules を workspace に保存すると、コミットのたびに新しい workspace が作られ、それぞれが15日間保持されます。一方、cache に保存すれば、package-lock.json が変わらない限り同じキャッシュを再利用するため、ストレージ使用量を大幅に削減できるわけです。

ストレージ使用量の試算

実際にどれくらいのストレージを使用しているのか試算してみました。対象プロジェクトの状況は次のとおりです。

過去15日間のコミット数は23回でした。node_modules の推定サイズは約400MBです。このプロジェクトは AWS SDK for JavaScript v3(S3とSSM)、Google Analytics Data API、LangChain と Anthropic SDK、googleapis、AWS CDK関連パッケージなどを使用しているため、それなりのサイズになります。

workspace を使用している場合、各コミットで新しい workspace が作られ、15日間保持されます。計算すると、400MB × 23個 = 約9.2GBのストレージを使用していることになります。

cache に移行した場合、package-lock.json が変更されたときだけ新しいキャッシュが作られます。過去15日間で package-lock.json が変更されたのは2〜3回程度だったため、400MB × 2〜3個 = 約1.2GB以下に抑えられます。

期待される削減量は約8GB以上です。これは無視できない差でしょう。

解決策の実装

CircleCIには Node Orb という公式パッケージがあり、このバージョン7.2.1には自動的にキャッシュ機能が組み込まれています。この機能を活用することにしました。

変更内容は3つあります。まず、install-node22 ジョブを削除しました。このジョブは node_modules を workspace に保存する処理を行っていたため、不要になります。

次に、各ジョブ(lint-node22、build-node22、test-node22)で node/install-packages を直接実行するようにしました。この設定により、各ジョブが独立して動作し、自動的にキャッシュを利用します。

最後に、ジョブ間の依存関係を削除しました。requires を削除することで、すべてのジョブが完全に並列実行されます。これにより、実行時間の短縮も期待できます。

変更後のワークフローでは、lint-node22、build-node22、test-node22 の3つのジョブが並列実行されます。各ジョブは独立して、リポジトリのチェックアウト、Node.jsのインストール、node/install-packages によるパッケージインストール(ここでキャッシュが自動利用されます)、各種タスクの実行という流れで動作します。

期待される効果

この変更によって4つの効果が期待できます。

ストレージ使用量の大幅削減は最大の目的です。約8GB以上の削減が見込まれるため、CircleCIの無料枠やストレージコストの面で大きなメリットがあります。

ジョブの並列実行により、実行時間が短縮されます。以前は install-node22 の完了を待ってから各テストジョブが実行されていましたが、今回の変更ですべてのジョブが同時に開始されるため、全体の実行時間が短くなります。

自動キャッシュ管理によって、運用負荷が軽減されます。Node Orb が package-lock.json の変更を検知して自動的にキャッシュを更新するため、手動でキャッシュキーを管理する必要がありません。

設定のシンプル化も実現できました。workspace の persist と attach を管理する必要がなくなり、設定ファイルの記述量が減りました。

まとめ

CircleCIの workspace と cache は似た名前ですが、保持期間と用途が大きく異なります。workspace はワークフロー内のジョブ間共有に適していますが、デフォルトで15日間保持されるため、node_modules のような大きなファイルを保存するとストレージを圧迫します。cache は異なるワークフロー間でファイルを再利用するため、依存関係ファイルの保存に適しています。

今回の事例では、workspace から cache への移行により約8GBのストレージ削減に成功しました。同様の問題を抱えているプロジェクトでは、workspace の使用状況を確認し、cache への移行を検討するとよいでしょう。CircleCIの公式Orbを活用することで、設定の変更も比較的簡単に実現できます。

シェア:

Hidetaka Okamoto profile photo

Hidetaka Okamoto

Developer Experience Engineer

Developer Experience Engineer。AWSやCloudflare上へのサーバーレスなアプリ開発を得意とする開発者。元Stripe Developer Advocate / AWS Samurai 2017など、サービスの使い方や活用Tipsを紹介するコンテンツ作成や登壇などを得意とする。

⭐ この記事への反応

はてなアカウントでスターを付けることができます

関連記事

CircleCIのworkspaceをcacheに切り替えてストレージ利用量を8GB節約する