運用作業

容量の計画と変更

復元時の余裕を計算し、対応するリソースサイズを変更します

作業内容

同時セッション数、worker メモリ、ノード数を計画し、対応する値を変更します。transcript と成果物の固定上限はストレージ契約が正本です。

準備

実際のノード allocatable、他の Pod requests、slot limit、workspace 使用量を確認します。transcript のサイズと compaction の有無で復元 peak が異なるため、平均使用量だけを見てサイズを小さくしないでください。

手順

1. 復元コストと安全余裕

基準は、compaction していない transcript の resume 時の最悪 peak が worker メモリ上限の半分以下であることです。残り半分は、最初の turn の作業、測定していない transcript の形状、エンジンのバージョン差に備える余裕です。

開発用の .env.example は WORKER_MEMORY_MB=2048 を設定しています。そのままでは上記の半分という基準を満たしません。大きな transcript の resume 試験では、その行を削除するか WORKER_MEMORY_MB=4608 に変更します。実際のデプロイ入力で適用される値も確認します。

測定方法

比較条件は fake model・cgroup v2 の Compose 環境です。source worker が合成 transcript を mirror に入れ、checkpoint を作って pause します。続いて新しい worker がその checkpoint を復元し、最初の resume turn を実行します。その間、0.5 秒ごとに worker コンテナの cgroup(memory.peak、anon、file、shmem、swap、oom_kill)とプロセスごとの VmHWM を記録しました。memory.peak には回収可能な page cache(file)も含まれますが、基準にも含めました。worker イメージは claude-agent-sdk 0.3.270、Claude Code CLI 2.1.270 です。

4608MiB 上限(現在の既定値)

transcriptcompaction最初の resume turnmemory.peak MiB(上限に対する割合)anonfileswapOOMworker(bun) VmHWMCLI VmHWM
511MiBなし成功1970 (43%)1054710005461129
511MiBあり成功1338 (29%)53371600588237
64MiBなし成功726 (16%)5587500504329

6144MiB 上限(比較測定)

transcriptcompaction最初の resume turnmemory.peak MiB(上限に対する割合)anonfileswapworker(bun) VmHWMCLI VmHWM
600.0MiBなし成功2178 (35%)130174506261308
600.1MiBあり成功1029 (17%)4536090497236
799.4MiBなし成功2785 (45%)166985205971727
799.1MiBあり成功1392 (23%)6719960716234
64.9MiBなし成功839 (14%)5082790437326
150.2MiBなし成功828 (13%)5011510487492

表の読み方

  • worker(bun) は transcript のサイズにかかわらず 440–720MiB を使います。restore を part 単位でストリーミングするためです。
  • サイズに比例するのはエンジン(CLI)の使用量です。compaction なしでは、およそ 210 + 1.85 × T MiB を使います(T は transcript の MiB)。511MiB では式の値は 1155MiB、実測は 1129MiB でした。compaction があれば、エンジンの使用量はサイズによらず約 235MiB です。
  • 全体 peak は page cache を加えると、150–800MiB の範囲で transcript 1MiB あたり約 3MiB 増加します(150.2MiB で 828MiB、600MiB で 2178MiB、800MiB で 2785MiB)。次の表の 256・400MiB は、この直線で補間した推定値です。

2. transcript 上限とメモリの選択

候補となる上限ごとに必要メモリとノードごとのセッション数を比較しました。メモリは 2 × peak を 512MiB 単位で切り上げた値です。セッション数は allocatable 30GiB(30720MiB)のノードを基準としています。標本が小さいため、この表だけで運用環境の上限を決めないでください。

上限compaction なしの peak半分基準のメモリノードごとのセッション分布中で上限以内80% 警告
256MiB1146MiB(推定)2560MiB1210/12204.8MiB
400MiB1578MiB(推定)3584MiB810/12320MiB
512MiB1970MiB(実測)4096MiB → 4608MiB611/12409.6MiB
600MiB2178MiB(実測)4608MiB612/12480MiB
800MiB2785MiB(実測)5632MiB512/12640MiB
  • 512MiB には観測した 12 件のうち 11 件が収まります。二番目に大きい 400.1MiB のセッションも警告に達しません。超えるのは 591.8MiB の一件です。このようなセッションは 409.6MiB で警告を受け、新しいセッションへ移ります。
  • 400MiB なら 400.1MiB セッションの checkpoint が直ちに拒否されます。256MiB なら 217MiB セッションも警告範囲に入ります。
  • メモリは 4096MiB ではなく 4608MiB です。512MiB の実測 peak 1970MiB に対し、4096MiB の半分(2048)では余裕が 78MiB しかありません。4608MiB なら 334MiB の余裕があります。

3. ノードごとの同時セッション数

sessions per node = floor((node allocatable memory - sum of other Pod requests on the node) / worker.memoryMb)

worker 専用ノードグループ(worker.nodeSelector、worker.tolerations)なら、他の Pod は DaemonSet 程度です。30GiB allocatable のノードで DaemonSet の使用分を 0 とすると次のとおりです。

worker.memoryMbノードごとのセッション
204815
4608(現在)6
61445

CPU も同じ式で数えます(worker.cpus、既定 1)。通常はメモリが先に埋まります。セッションごとに workspace PVC(worker.workspace.quotaMb、既定 4096MiB)も一つ付きます。復元した transcript(最大 512MiB)は作業ツリー、git objects、restore spool とともにこの中へ収まる必要があります。

local Docker 実行基盤では、一台のメモリを EXECUTION_SLOT_LIMIT(既定 10)個の worker で分け合います。上限は cgroup の制限であり予約ではないため、同時に使い切らなければ合計が超過していても動作します。それでも slot 数 × 4608MiB がマシンのメモリを大幅に超えれば OOM が起きます。

変更方法の選択と対応状況

方法操作得られるもの代償
① worker.memoryMb を下げるvalues の値を一つ変更します(WORKER_MEMORY_MB、次の launch から適用)ノードごとのセッション数が増えます。例えば 3584MiB なら 30GiB ノードに 8 件ですcompaction なしの大きな transcript を resume する余裕も減ります。半分基準を守るには上限も下げる必要があります(3584MiB なら上限約 400MiB、推定)。上限はコード定数なのでビルドが必要です
②(現在未対応)requests を limits より小さくするオーバーコミットchart の worker Pod requests を limits より小さくします小さなセッションが多い場合、ノードごとのセッション数を大きく増やせます。実測では 64–150MiB transcript の resume peak は 726–839MiB でした現在の chart と scheduler は requests = limits でのみ Pod を作成します。変更にはコード修正が必要です。QoS が Burstable に下がり、大きなセッションが複数同時に resume するとノードのメモリ圧迫で OOM kill や eviction が起きます
③ ノードグループを拡大するworker ノード数またはノードサイズを増やしますセッションごとの保証を維持して総セッション数を増やします費用が増えます。コード変更はありません
④(現在未対応)セッションサイズ別の Pod サイズ復元する transcript のサイズから scheduler が Pod メモリを選びます小さなセッションは小さく、大きなセッションだけ大きく起動しますコード修正が必要です。scheduler が launch 前に checkpoint サイズを把握する必要があり、実行中に同じ Pod 内で transcript が大きくなる場合も別途扱う必要があります

上限(MAX_TRANSCRIPT_BYTES)だけを上げてメモリを据え置くことは推奨しません。compaction なしの大きな transcript の resume が上限に達すると、worker が再起動を繰り返し、セッションが recovery_required になります。上限変更時はこの文書の方法で再測定します。

メモリ値は次の launch から適用され、実行中の worker は置き換わりません。上限を変更する自前ビルドでは API と worker を同じリリースにする必要があるため、アップグレードゲートに従います。

API だけが小さい transcript 上限を使うと、worker では上限以内の checkpoint も finalize が拒否し、transcript_too_large を記録して新しい turn を止める場合があります。API と worker の上限を揃えます。新しい transcript reason を知らない以前の API は報告を 400 で拒否するため、migration → API 全インスタンス → worker の順を守り、その reason を知るビルドまでしか rollback しません。

4. provider 費用と上限の照合

使用量と費用の計測で推定・fallback 単価・再認可の境界を確認し、実際の provider 請求と比較します。設置上限の変更・適用には、モデル接続と backend ごとのアップグレード手順に従います。

確認

変更前後に同じ checkpoint を新しい worker で復元し、turn 完了、memory.peak、OOM、ディスク、inode、queue wait を比較します。表の数値は記載した SDK・CLI・合成 transcript の条件でのみ観測した値であり、運用環境や新しい runtime の実測の代わりにはなりません。

よくある問題

transcript 上限だけを上げてメモリを据え置くと、再起動後に recovery_required になる場合があります。requests を limits より小さくするオーバーコミットと、セッションサイズ別の Pod サイズには現在対応していません。

元に戻す

新しい launch に適用するメモリ、slot、ノード数を以前の値に戻します。既存 workspace の byte quota を勝手に変更したり volume を削除したりしないでください。quota 契約の変更は workspace の移行に従います。

次に読む

ストレージと上限、メトリクス収集、隔離の説明。

このページ