CLAUDE_CODE_TOOL_MEMORY_LIMITでBash・PowerShellのメモリを制限する
CLAUDE_CODE_TOOL_MEMORY_LIMITはLinux/WSLでBash・PowerShell・Monitorのメモリ使用量にcgroupで上限をかける環境変数です。値の書き方、静かに失敗する2つの場面、除外設定を扱います。
CLAUDE_CODE_TOOL_MEMORY_LIMITは、LinuxとWSL上でBash・PowerShell・Monitorツールが実行するコマンドのメモリ使用量に上限をかける環境変数です。ビルドやテストの暴走で1本のコマンドがメモリを使い切り、セッション全体が重くなる事態を防ぎます。v2.1.233(2026年8月14日)で追加されました。
この変数には、失敗しても画面に何も出ない場面が2つあります。上限が効いていない場合と、上限に当たって落ちた場合です。どちらも原因が見えにくいので、設定の手順と合わせて切り分け方を先に押さえておくと迷いません。 上限をかけたい典型例として、ntfs3のジャンクションでfindが止まらずメモリを使い切る報告があります。
上限がかかる3つのツール
Bashツールがシェルコマンドを動かし、PowerShellツールがPowerShellのコマンドを動かします。Monitorツールは少し性格が違い、ログの追跡やCIの状態確認のように、バックグラウンドで走り続けるスクリプトを動かします。WebSocketのフィードに接続して届いたメッセージを報告させる使い方もあります。Monitorの監視には期限があり、既定は5分、最長で30分です(-pの単発実行では最長10分)。
この3つが1つの枠を分け合います。ただしMonitorがキャップの内側に入ったのはv2.1.246以降で、それより前のバージョンでは、Monitorのコマンドは上限の外で動いていました。
前面で動くBashコマンドの既定タイムアウトは2分、モデルが指定できる上限は10分です。それぞれ環境変数のBASH_DEFAULT_TIMEOUT_MSとBASH_MAX_TIMEOUT_MSで変更できます。タイムアウトに達した前面のコマンドは、止められずにバックグラウンドへ移されます(sleepで始まるコマンドを除く)。-pやCIのような無人のセッションでは、バックグラウンドのコマンドに30分(最大2時間)の時間制限がかかります。手元の端末で作業するローカルセッションには、この時間制限はありません。
設定から反映までの流れ
設定は4ステップで済みます。ただし最後の再起動を省くと、値を変えても効きません。
上限をかけるまでの4ステップ
- 1
環境がLinuxかWSLかを確かめる
対象はLinuxとWSL(Windows Subsystem for Linux)だけです。macOSとネイティブWindowsは、変数の説明に含まれていません。
- 2
バージョンを確かめる
変数自体はv2.1.233以降です。Monitorツールも対象にするならv2.1.246以降が必要です。
- 3
値を決めて設定する
4Gのような書き方でシェルかsettings.jsonに置きます。書式は次の節にあります。 - 4
claudeを起動し直す
キャップの有効・無効は最初のプロセスが決め、その結果は再起動まで固定されます。
バージョンは次のコマンドで確かめます。
claude --version値の書き方
サイズはバイト数の数字だけ、またはK・M・G・Tの接尾辞を付けて書きます。上限を切りたいだけなら4Gで十分で、正確なバイト数を計算する必要はありません。
| 書き方 | 扱われ方 |
|---|---|
4000000000 | 扱われ方バイト数の数値としてそのまま解釈 |
4G | 扱われ方4ギガバイトとして解釈(K/M/Tも同様) |
0 / off / false / no / none | 扱われ方キャップを無効化 |
4e9のような指数表記 | 扱われ方サイズとして読み取れないため無視される |
環境変数のリファレンスでは、タイムアウトやトークン数などの数値変数は2e3のような指数表記も読むと説明されています。この変数の行には「plain digits」で書くとあり、同じ感覚で4e9と書くと無視されます。無視されるとエラーは出ず、キャップなしのまま動きます。設定したつもりで上限が効かないときは、まず値の書式を疑うのが早道です。
上限は1セッションで1つの共有枠
この変数が管理するのは、1つのセッション内のBash・PowerShell・Monitorコマンド全体で使えるメモリの合計量です。コマンドごとに個別の枠が割り当てられるわけではありません。
4Gを設定したときの2つのビルド
個別枠だと思った場合
2つのビルドを同時に走らせても、それぞれ4ギガバイトまで使えると見込みます。
実際の共有枠
片方が3ギガバイトを使えば、もう片方の残りは1ギガバイトです。並列実行を前提にするなら、同時に走る最も重いコマンドの合計を見込んで値を決めます。たとえば3ギガバイト使うビルドと2ギガバイト使うテストを同時に走らせるなら、4Gでは足りず、6G程度が出発点になります。
静かに失敗する2つの場面
どちらの場面でも、通常の実行結果にはメモリキャップへの言及が出ません。見分けるときは、コマンドが落ちたのか、そもそも上限が効いていないのかを分けて考えます。
キャップが効かないときと当たったとき
効いていない
Claude Codeは上限をメモリcgroup(control group、Linuxのリソース管理機能)で実現します。cgroupを用意できない環境では、コマンドは上限なしで実行され、理由はclaude --debugのデバッグログに出ます。
当たって落ちた
上限を超えそうなコマンドは、Linuxカーネルに強制終了されます。コマンドの結果には、キャップが原因だとわかる情報が含まれません。
デバッグログは--debug-file <path>でファイルに残せます。このオプションを指定すると、デバッグモードも暗黙に有効になります。ログをファイルに残しておけば、再起動後に落ち方と照らして読めます。
export CLAUDE_CODE_TOOL_MEMORY_LIMIT=4G
claude --debug-file ./claude-debug.log設定場所と反映のタイミング
シェルの環境変数として渡すか、claudeを起動する前にエクスポートします。
export CLAUDE_CODE_TOOL_MEMORY_LIMIT=4G
claudeプロジェクトで固定値を共有したい場合は、settings.jsonのenvキーに書きます。
{
"env": {
"CLAUDE_CODE_TOOL_MEMORY_LIMIT": "4G"
}
}シェルとsettings.jsonのenvの両方に同じ変数があるときは、多くのセッションでenv側の値が使われます。シェルの値を残すセッションの条件は、設定リファレンスのenvの項に書かれています。チーム共有の.claude/settings.jsonに書いておけば、開発者ごとのシェル設定に左右されず同じ上限をかけられます。
どこに書くかは、誰に効かせたいかで決まります。
| 置き場所 | 効く範囲 |
|---|---|
~/.claude/settings.json | 効く範囲自分のすべてのプロジェクト |
.claude/settings.json | 効く範囲そのフォルダで作業する全員(gitで共有) |
.claude/settings.local.json | 効く範囲自分のそのプロジェクトだけ(試験に向く) |
| 管理者配信の設定 | 効く範囲組織の全員(上書きできない) |
ここで注意したいのは、settings.jsonのenvは保存すると実行中のセッションにも反映される点です。一般の環境変数ならファイルを保存した時点で効きますが、この変数は違います。最初のプロセスがキャップを有効化または無効化した時点で結果が固定されるため、値の変更や削除、cgroupの準備の修正は、claudeを起動し直すまで反映されません。
CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDEで対象を調整する
キャップの対象は、Bash・PowerShell・Monitorのコマンドだけではありません。Claude Codeが起動するほかの種類のプロセスも、同じ上限に数えられます。CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDE(v2.1.246以降)は、そのうちどの種類を対象外にするかをカンマ区切りで指定する変数です。
| 指定できるkind | 対象 |
|---|---|
mcp | 対象ローカルで動くMCPサーバー |
lsp | 対象言語サーバー |
hooks | 対象フックコマンド |
plugin | 対象プラグインが実行するコマンド |
helper | 対象Claude Code自身のヘルパーコマンド(gitなど) |
agent | 対象子のClaude Codeプロセス(Agent Teamsのteammateなど) |
一覧にない名前は無視されます。特別な値は2つで、noneはすべての種類をキャップの対象にし、all-newはBash・PowerShell・Monitor以外をすべて対象外にします。Bash・PowerShell・Monitorは、何を列挙しても常にキャップの内側に残ります。
この変数を設定しない場合、どの種類が既定で対象外になるかは、Anthropicがサーバー側から配信する設定で決まり、時間とともに変わりえます。対象の範囲を固定したい構成では、明示的に設定しておくのが確実です。
ローカルのMCPサーバーや言語サーバーがメモリを多く使う構成で、Bash・PowerShell・Monitor以外は上限の計算に含めたくないなら、次のように設定します。
export CLAUDE_CODE_TOOL_MEMORY_LIMIT=4G
export CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDE=mcp,lsp,hooks,plugin,helper,agent
claudeMCPサーバーだけを外したいならmcpの1語で足ります。現在の6種類をすべて並べたこの設定は、all-newを指定した場合と同じ効果です。逆に、フックやプラグインの暴走までキャップで守りたいならnoneを指定します。
バージョンごとの違い
| バージョン | 追加された内容 |
|---|---|
| v2.1.233 | 追加された内容CLAUDE_CODE_TOOL_MEMORY_LIMITが登場。changelogの記述はBashツールのコマンドを対象とするオプトイン機能 |
| v2.1.246 | 追加された内容Monitorツールのコマンドが上限の内側に入る。CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDEも同じバージョンから |
公式ページ同士で書き方が揺れています。v2.1.233のchangelogはBashツールだけを挙げています。Week 33のアップデート告知はBashとPowerShell、現在のツールリファレンスはMonitorを加えた3つです。古いバージョンを使うチームでは、Monitorが上限の外にある点だけは確実なので、長時間の監視コマンドにも枠が必要ならv2.1.246以降へ上げます。
似た名前の環境変数との使い分け
「上限」を意味する変数はほかにもあり、制限する対象がそれぞれ違います。名前の響きが近いので、対象を表で見比べます。
| 変数 | 制限する対象 | 対応環境 |
|---|---|---|
CLAUDE_CODE_TOOL_MEMORY_LIMIT | 制限する対象Bash・PowerShell・Monitorコマンドが使えるメモリ量 | 対応環境Linux/WSLのみ |
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS | 制限する対象同時に実行中のサブエージェント数 | 対応環境全環境 |
CLAUDE_CODE_MAX_TURNS | 制限する対象セッションが進められるターン数 | 対応環境全環境 |
CLAUDE_CODE_MAX_OUTPUT_TOKENS | 制限する対象1回の応答で出力できるトークン数 | 対応環境全環境 |
メモリという物理リソースを制限するのはこの変数だけで、残りは実行回数やトークン数のような論理的な数量を制限します。環境変数全体の一覧はClaude Code環境変数リファレンスにまとめています。
メモリ起因のトラブルとの関係
GitHubのissueでは、メモリ枯渇でホストごと固まる報告が見つかります。たとえばissue #54394は、v2.1.117の同梱ugrepラッパーが正規表現のバックトラッキングで暴走し、WSL2でホストが固まったという報告で、クローズ済みです。issue #91081は、エージェントが起こすプロセス群にメモリ上限や圧力のフィードバックを求める要望で、オープンのままです。
この変数が上限をかけるのは、Bash・PowerShell・Monitorのコマンドと、除外しなかった種類のプロセスです。Claude Code本体のプロセスが膨らむ問題は別の話です。原因と対処はClaude Codeのメモリリークとその対処で扱っています。セルフホストRunnerでセッション同士の巻き込みを避けたい場合は、コンテナ単位のメモリ上限で分けます。カーネルの厳格なovercommit設定で確保が失敗する場合は、vm.overcommit_memory=2での切り分けが別の原因になります。
Bashツールの挙動では、シェル関数がコマンドにどう見えるかという別の落とし穴もあります。zoxideが使えない原因にまとめました。
持ち帰る判断
Claude CodeをLinux/WSLで使うなら、4Gのような値を1つ置いて再起動します。値は、同時に走るビルドやテストの合計メモリから見積もります。
MCPサーバーや言語サーバーが重い構成では、CLAUDE_CODE_TOOL_MEMORY_CGROUP_EXCLUDEで外すかどうかが分かれ目です。理由不明のビルド落ちが出たら、上限の値とclaude --debugのログを最初に見てください。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。