MAX_TOOL_USE_CONCURRENCYとMAX_CONCURRENT_SUBAGENTSの違い
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYとCLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSは似た名前ですが、対処するエラーも挙動も別物です。症状別の選び方と超過時の挙動差を示します。
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYとCLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSは、どちらも「並列数の上限」を扱う環境変数です。名前にCONCURRENCYとCONCURRENTが並ぶので混同しやすく、片方を上げても目当てのエラーは消えません。画面に出たエラー文がどちらなのかで、触る変数が決まります。
エラー文がRequest rejected (429)なら前者、Concurrent subagent limit reachedなら後者です。前者はAPIのレート制限への対処としてエラー一覧に載り、後者はサブエージェントの起動拒否としてサブエージェントのページに載っています。
症状から変数を決める
エラー文から触る変数を選ぶ
- 1
エラー文をそのまま読む
API Error: Request rejected (429)で始まるのか、Agentツールの結果にConcurrent subagent limit reachedと出ているのかを見ます。名前や並列数の体感では選びません。 - 2
429なら、並列度を下げる側へ動かす
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYを下げます。エラー一覧は同じ項目で、並列サブエージェントを減らすことと、/modelでより小さいモデルへ切り替えることも挙げています。 - 3
起動拒否なら、上限を上げる側へ動かす
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSに正の整数を入れます。実行中のサブエージェントが上限を下回れば、新規の起動はまた通ります。
429は並列度だけが原因とは限りません。エラー一覧は、まず/statusで使っている認証情報が想定どおりかを見るよう挙げています。環境に残ったANTHROPIC_API_KEYが、サブスクリプションではなく低いティアのキーへリクエストを流すことがあるためです。プロバイダーのコンソールで上限を調べ、必要ならティアの引き上げを申請する手もあります。
エラー文の末尾の案内は、プロバイダーによって変わります。Amazon BedrockやGoogle Cloud、Microsoft Foundryでは、それぞれの稼働状況ページが示されます。
429のとき、CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSは対処に挙がりません。逆に起動拒否のとき、CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYを上げても拒否は止まりません。後者の拒否はサブエージェントのページが「Agentツールでの起動」について定めた別の上限だからです。
それぞれが数えるものの違い
2つの上限が数えるもの
MAX_TOOL_USE_CONCURRENCY
「並列に実行できる読み込み専用のツールとサブエージェント」の最大数です。env-varsの行は、値を上げると並列度が増えてリソースも消費するとも書いています。バージョン要件の記載はありません。
MAX_CONCURRENT_SUBAGENTS
1セッションで同時に動いているサブエージェントの数です。上限に達するとAgentツールが次の起動を拒否します。v2.1.217以降の変数です。
前者の定義は「読み込み専用のツール」と限定されています。定義上、対象はRead・Grepのような参照系のツールとサブエージェントです。個別の解説はClaude Code「Tool Use Concurrency」エラーの原因と対処法にあります。
後者は、ClaudeがAgentツールで新規に起動するサブエージェントだけを止めます。詳しい挙動はCLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSとはにまとめました。
似た名前の変数がもう1つあります。CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHは並列数ではなく、サブエージェントが子サブエージェントを何階層まで持てるかを決める変数で、既定は3です。CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHとはで扱っています。
上限に達したときの挙動の差
上限を超えたときに何が起きるかが、実務ではいちばん効きます。後者は起動そのものが失敗します。サブエージェントのページによると、20件が動いている状態でAgentツールを呼ぶとConcurrent subagent limit reachedで失敗し、エラーはClaudeにリトライしないよう伝えます。
前者のenv-varsの行には、10を超えた分が拒否されるのか待たされるのかの記載がありません。「並列に実行できる最大数」という定義からは、同時に走るのが10までになるという読み方が自然です。
既定値の10と20に件数を当てはめると
2つの上限は別々の上限なので、値の大小だけでは先に詰まる側が決まりません。既定値(10と20)を当てはめた例を見ます。
Agentツールで15件の起動を試すと、20件の天井には届かないので起動は拒否されません。15件のうち10件を超える分の扱いは、env-varsの行に書かれていません。
25件を一度に試すと、21件目以降はConcurrent subagent limit reachedで拒否されます。実行中の何件かが終わって20を下回るまで、新規の起動は通りません。
普段の使い方で起動する件数が10にも届かなければ、どちらの上限も意識する場面はありません。大規模なレビューや一括処理で件数が既定値に近づくときが、見積もりの出番です。
数値の書式にも違いがある
env-varsページの冒頭には、数値の環境変数に共通するルールがあります。タイムアウトやトークン予算のような数値変数は、桁区切り(64_000)や指数表記(2e3)も受け付けます。例外は、行に「plain digits only」の注記がある変数です。
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSの行は「plain digits」と明記しています。正の整数以外の値(0・負の数・小数・文字列・桁区切り・指数表記)は無視されて既定の20のままです。行には「上限を調整はできるが無効にはできない」ともあり、0を入れても無制限にはなりません。
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYの行にこの注記はありません。共通ルールの例外注記が行にないので、桁区切りや指数表記も対象と読めます。
導入されたバージョンと変遷
2つの変数は、サブエージェント周りの上限が段階的に整った流れの中にあります。
サブエージェントの上限をめぐる変更
- v2.1.217同時実行数の上限が入る
既定20、
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSで変更できます。同じリリースでサブエージェントの入れ子が既定でオフになり、--max-budget-usdの上限に達した後は新規の起動が拒否され、動いているバックグラウンドエージェントも止まるようになりました。 - v2.1.219入れ子の既定が3階層に
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHの既定が1から3に上がり、サブエージェントが子を持てるようになりました。 - v2.1.2241セッションの総数上限が撤廃
「サブエージェント200件」という起動総数の上限が外れました。長時間のセッションでも新しいエージェントを拒否されなくなり、同時実行数と深さの上限だけが残っています。
v2.1.217より前の環境では、CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSを設定しても効きません。古いバージョンのCIイメージで固定しているときは、先にバージョンを見ます。
ultracodeと、上限の数え方の例外
/effort ultracodeで入るultracodeモードのセッションでは、CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSの上限が強制されません。CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYの行に、ultracodeの免除は書かれていません。
後者の上限チェックが働くのは、ClaudeがAgentツールで新規に起動するときだけです。それ以外の実行は同じスロットを使いながら、チェックだけを素通りします。
/subtaskで会話をフォークして走らせる実行は、動いている間スロットを1つ使います。ただし上限を超えていても常に成功します- 完了済みのサブエージェントを再開する操作は、上限を確かめずに新しいスロットを使います。上限ぎりぎりで複数を再開すると、同時実行数が設定値を一時的に超えます
- ワークフローのエージェントやエージェントチームのチームメイトは、このセッション内の上限ではなく、それぞれの機能の上限に従います
起動の総数には上限がなく、制限があるのは同時実行数と入れ子の深さだけです。大量にサブエージェントを使う運用では、同時実行数よりも積み上がる支出の総量が論点になります。
設定のしかたと反映のタイミング
シェルの環境変数か、settings.jsonのenvキーで設定します。
export CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=20
export CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS=40
claudeプロジェクトで値を共有するなら、.claude/settings.jsonに両方まとめて書けます。値は文字列で渡します。
{
"env": {
"CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY": "20",
"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS": "40"
}
}反映のタイミングは、書いた場所で変わります。シェルの値は起動時に読まれるため、変えたらclaudeを起動し直します。settings.jsonのenvの値は、ファイルを保存すると、動作中のセッションの環境に再適用されます。ただし設定ファイルからのenvの削除は、動作中のセッションの環境から変数を取り除きません。
同じ変数をシェルとsettings.jsonの両方に書いた場合、env-varsページは「ほとんどのセッションでは設定ファイルの値が使われる」と説明しています。
大量のファイルをサブエージェントで並列に処理するなら、同時数を上げるのはCLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSです。429が出る環境では、並列度を下げる側のCLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYも併せて見ます。支出を抑えたいCIでは、Agent SDK経由ならAgent SDKのサブエージェント上限のmaxBudgetUsdが使えます。
2つの変数で解決しない症状の早見表
| 症状 | 見る先 |
|---|---|
| サブエージェントが孫を起動できない | 見る先CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH(v2.1.219以降の既定は3) |
| 値を入れたのに20のまま変わらない | 見る先値の書式と、v2.1.217以降かどうか |
| 20件を超えて動いている | 見る先ultracode、/subtask、完了済みの再開のいずれか |
| 429が続く | 見る先/statusの認証情報、環境に残ったANTHROPIC_API_KEY、ティア |
まとめ
普段の起動数が10に届かない使い方なら、どちらも既定値のままで足ります。一括処理やCIで触るときは、エラー文で変数を選び、効かなければバージョン、値の書式、認証情報の順に疑う流れになります。