Claude Codeのバックグラウンドが時間制限で止まる原因と延ばし方
Claude Codeのバックグラウンド実行が「background time limit」で止まる原因を、版と実行形態から切り分けます。GitHub issue #98273の要望と、延ばす設定も扱います。
Claude Codeでrun_in_backgroundのコマンドを走らせていて、30分前後で「was stopped after reaching its background time limit」と止められたなら、原因はバックグラウンドコマンドの時間制限です。v2.1.285で入り、v2.1.288で無人実行だけに絞られました。端末で対話している場合は、v2.1.288以降なら制限は掛かりません。
この制限をめぐっては、GitHub issue #98273が「未文書のまま長時間ジョブが途中で切られる」と報告しています。この記事では、止まったときの切り分け、制限を延ばす設定、延ばさずに済ませる設計を扱います。Ctrl+Bでの切り替えや出力上限など、Claude Codeのバックグラウンド実行の使い方はClaude Codeバックグラウンド実行にあります。
止まったときに何が起きるのか
制限に達したコマンドは、Claude Codeが止めます。Claudeには次の通知が渡ります。
Background command "<説明>" was stopped after reaching its background time limit通知を受けたClaudeは、もっと長いtimeoutを付けて同じコマンドを起動し直せます。つまり仕様上は「止める」のであって、警告なしに黙って消えるわけではありません。ただし止まる前の予告はなく、通知は止まった後に届きます。issueの報告者が困ったのもこの点でした。
issueの本文によると、報告者は別のCLIエージェントに委譲したコーディングや監査のジョブをrun_in_background: trueで動かしていました。30〜60分以上かかるジョブが、timeoutを一度も指定していないのに止められたそうです。外部ツール側がセッションをディスクに保存していたため、復旧できたと書かれています。
制限は誰に掛かるのか
時間制限の対象は、バックグラウンドのBashとPowerShellコマンドです。掛かるかどうかは、Claude Codeのバージョンと実行形態の組み合わせで決まります。
| 実行形態 | v2.1.285〜v2.1.287 | v2.1.288以降 |
|---|---|---|
| 端末の対話セッション | v2.1.285〜v2.1.287制限あり | v2.1.288以降制限なし |
| デスクトップアプリ・VS Code拡張 | v2.1.285〜v2.1.287制限あり | v2.1.288以降制限なし |
-p・Agent SDK・CI・クラウドセッション | v2.1.285〜v2.1.287制限あり | v2.1.288以降制限あり |
v2.1.285より前に制限はありません。v2.1.288のchangelogは、制限を「無人のセッションだけに適用する」変更として書いています。
したがって切り分けの順序はこうなります。
制限で止まったかを切り分ける
- Q通知に background time limit の文言が出ていますか?答えが別の停止要因です。下の見分け表を見てください答えがはい
次の問いに進みます。
- QClaude Codeのバージョンはv2.1.287以前ですか?答えが次の問いに進みます答えがはい
v2.1.288以降へ更新すると、対話セッションでは制限が掛からなくなります。
- Q`-p`・Agent SDK・CI・クラウドで動かしていますか?答えが通知の出どころを再確認してください。対話セッションでv2.1.288以降なら、この制限は対象外です答えがはい
無人実行なので制限は残ります。次の節の環境変数で延ばせます。
原因は無人実行の時間制限
既定は30分です。Claudeがtimeoutを渡せば最大2時間まで延びます。
更新だけで外れるのは対話セッションの制限で、-pやCIの制限は更新しても残ります。
issueが立った時点の報告者の環境は、本文からは分かりません。バージョンと実行形態を確かめてから、自分のケースに当てはめてください。
数え方と既定値
制限は、コマンドがバックグラウンドに入った時点から数えます。
- Claudeが最初からバックグラウンドで起動したコマンドは30分。Claudeが
run_in_backgroundと一緒にtimeoutを渡せば、その値で、最大2時間まで - フォアグラウンドで始まり、タイムアウトや
Ctrl+Bで移ったコマンドは、移った時点から30分 -pでプロンプトをテキストとして渡す実行では、どちらの既定も30分でなく10分
-pの10分は、結果を返したあとも実行がバックグラウンドコマンドの完了を待つためです。この待ちの挙動はヘッドレスモード(-p)の記事で扱っています。
時間制限とは別に、sleepで始まるコマンドはタイムアウトに達してもバックグラウンドへ移らず、そのまま停止します。sleep 3600 && ./check.shのように待機から始めるジョブの監視は、この経路に当たります。待機をスクリプトの中に入れ、コマンドの先頭をsleep以外にすれば、この停止は起きません。
延ばす設定
延ばす手段は環境変数2つです。どちらもミリ秒で指定し、短くする方向には働きません。
| 変数 | 効果 |
|---|---|
BASH_DEFAULT_TIMEOUT_MS | 効果1800000より大きくすると、30分の既定がその値に置き換わる。timeoutなしで起動したコマンドと、移ったコマンドの両方に効く。-pでテキストを渡す実行だけは、10分の既定を置き換える閾値が600000 |
BASH_MAX_TIMEOUT_MS | 効果7200000より大きくすると、2時間の最大がその値に上がる |
BASH_DEFAULT_TIMEOUT_MSを7200000より大きくした場合も、最大が同じ値に上がります。たとえば6時間まで許したいなら、設定ファイルのenvに次のように書きます。
{
"env": {
"BASH_DEFAULT_TIMEOUT_MS": "21600000"
}
}シェルから渡す場合は、claudeを起動する前に変数を設定します。
export BASH_DEFAULT_TIMEOUT_MS=21600000
claude -p "夜間の監査ジョブを実行して"注意点が1つあります。BASH_DEFAULT_TIMEOUT_MSは、フォアグラウンドのコマンドの既定タイムアウトでもあります。値を大きくすると、手前のコマンドが自動でバックグラウンドへ移るまでの待ち時間も、同じだけ延びます。細かい挙動はBASH_DEFAULT_TIMEOUT_MSの記事にまとめています。
issueが求めた「設定で無効にする」に近づけるには、十分大きな値を入れる方法になります。tools-referenceの「Time limit for background commands」の節が示すのは延ばす方法だけで、制限を切る設定はありません。バックグラウンド実行そのものを止めたいときは、CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1がありますが、run_in_backgroundが使えなくなるので目的が違います。一覧は環境変数リファレンスにあります。
最初から裏で起動するか、途中で裏へ移すかで延ばし方が変わる
同じ30分でも、コマンドが裏に入った経路で、コマンド単位の調整ができるかどうかが分かれます。
コマンド単位で延ばせるのは最初から裏で起動したときだけ
最初から裏で起動
Claudeがtimeoutを渡せば、その値が制限になります。最大は2時間で、BASH_MAX_TIMEOUT_MSを上げればさらに延びます。長いジョブと分かっているなら、この経路が確実です。
途中で裏へ移った
移った時点から30分で固定です。呼び出しごとに延ばす手段はなく、延ばすならBASH_DEFAULT_TIMEOUT_MSで全体の既定を上げます。
「走らせてみて長引いたら裏へ」という使い方は、無人実行では30分で切られる前提になります。夜間バッチやCIで30分を超えると分かっているジョブは、最初からバックグラウンド起動とtimeoutの指定をプロンプトで求める形にすると、30分を超えるジョブも通せます。
claude -p "ビルド後の統合テストを run_in_background で起動し、\
timeout は 1 時間にして。完了したらログの末尾を要約して"-pでテキストのプロンプトを渡す実行は、既定が10分に下がります。上のようにClaudeがtimeoutを1時間で渡すなら、その値が制限になるので、既定を上げる必要はありません。BASH_DEFAULT_TIMEOUT_MSを600000より大きくする意味があるのは、timeoutを渡さずに起動したコマンドや、途中でバックグラウンドへ移ったコマンドも長く走らせたいときです。Claudeが渡すtimeoutの最大は2時間のままです。
起動しているバージョンは、報告や設定の前に確かめておくと原因の切り分けが早く済みます。
claude --versionissue #98273の要望と現状
issueは3点を求めています。issueはopenで、ラベルはenhancementとarea:bashです。
| 要望 | 現状 |
|---|---|
| 制限を文書化する | 現状tools-referenceに「Time limit for background commands」の節がある |
| コマンド単位か設定で変更・無効化できるようにする | 現状コマンド単位はrun_in_backgroundと一緒に渡すtimeout、全体は上の2変数。無効化する設定はない |
| 止める前に警告する | 現状停止前に予告する仕組みはなく、通知は停止後に届く |
コメントには、制限がv2.1.285で入った変更だと指摘する書き込みと、長時間の監視やジョブのキューイングが途中で終わって作業時間を失ったという報告、制限の撤廃を求める声が並んでいます。止める前の警告の仕組みは、まだ入っていません。
延ばさずに済ませる設計
制限を延ばしても、2時間や6時間を超えるジョブは残ります。止められても被害が小さくなる形に寄せておくと、制限の値に振り回されません。
- 長時間のジョブは、自前で進捗をディスクに保存する。issueの報告者の外部ツールがセッションを保存していたので復旧できたのは、この形です
- 出力は標準出力に頼らず、ログファイルへ書かせる。止まったあとでもClaudeがファイルを読んで、どこまで進んだかを判断できる
- 再起動すると続きから進む形にする。Claudeが通知を受けて起動し直したとき、最初からやり直しにならない
Claudeに起動し直させる前提なら、CLAUDE.mdに方針を書いておく手があります。例えば次のような断片です。
## 長時間ジョブの扱い
- 30分を超えるコマンドは run_in_background で起動し、timeout を明示する
- "background time limit" で止まったら、進捗ファイルを読んで続きから再開する
- 進捗は ./progress.json に書き、完了確認はこのファイルで行うこの断片はあくまで一例で、Claudeがこの指示に必ず従うとは限りません。進捗ファイルの形式やパスはジョブ側で決めてください。
ほかの停止との見分け方
バックグラウンドの処理が止まる理由は、時間制限のほかにもあります。通知の文言と対象で見分けられます。
| 止まり方 | 対象 | 詳細 |
|---|---|---|
| background time limit | 対象v2.1.285以降(v2.1.288からは無人実行のみ)のBash・PowerShell | 詳細この記事 |
| Monitorの期限 | 対象Monitorツールの監視 | 詳細Monitorのpersistentが廃止され30分で切れる理由 |
| メモリ逼迫・出力量・サブエージェント終了 | 対象裏のコマンド全般 | 詳細Claude Codeバックグラウンド実行の「裏のコマンドはいつ止まるか」 |
| WSL2のlow memory | 対象WSL2上のバックグラウンドタスク | 詳細WSL2の誤検知の記事 |
Monitorの30分とBashの30分は数字が同じですが、別の仕組みです。ログの監視に使っているのがMonitorなら、Bashの環境変数を変えても期限は延びません。
まとめ
30分前後でバックグラウンドコマンドが止まり、通知に「background time limit」とあれば、原因はこの時間制限です。対話セッションならv2.1.288以降への更新で解消し、-pやCIならBASH_DEFAULT_TIMEOUT_MSとBASH_MAX_TIMEOUT_MSで延ばせます。それでも長いジョブは、進捗の保存と再開を前提にした形にしておくのが確実です。止める前の警告を求めるissueは、openのまま残っています。