コンテンツにスキップ

アイドル停止と強制停止を使う

使われていないセッションとワークスペースは、自動で止まります。終わらない起動や応答しない Agent も見つけて止められ、しばらく誰も使わない配備は丸ごと一時停止できます。 止まるまでの時間や止めかたを、配備の側で決めます。

あなたがやること 起きること
何もしない 使われていないセッションとワークスペースが、配備の既定の時間で止まる。終わらない起動も止まる
環境変数で配備の既定を変える すべてのテナントの既定が変わる。テナントは管理画面で上書きできる
応答しない Agent の自動停止を有効にする 「応答なし」のまま時間を過ぎたワークスペースを止める
管理画面からワークスペースを強制停止する そのワークスペースが確実に止まる
pause.sh で配備を一時停止する 時間で課金されるものが止まり、データは残る

既定の時間は 上限と既定値 にあります。テナント管理者から見た動きは 放置されたワークスペースを止める にあります。

アイドル自動停止の時間を決める

Section titled “アイドル自動停止の時間を決める”
環境変数 止まるもの
AF_SESSION_IDLE_TIMEOUT 使われていないセッション
AF_INTERACTION_IDLE_TIMEOUT 質問や承認を待って止まっているセッション
AF_WS_IDLE_TIMEOUT 何も動いていないワークスペース
AF_BACKGROUND_HOLD_MAX バックグラウンド作業がワークスペースを起こしておける時間の上限。0 を指定すると無制限になります
AF_PRESENCE_IDLE_TIMEOUT 打鍵のない端末を「在席」と数える猶予
  • 環境変数に 0 を指定すると、配備全体で無効になります
  • テナントごとの値は、管理画面の上限の「アイドル自動停止」にある 4 つの欄(セッション停止まで・判断待ちの halt まで・バックグラウンド作業で保持する上限・ワークスペース停止まで)で決めます。空欄なら配備の既定に従い、0 ならそのテナントだけ無効です
  • 環境変数の意味は deploy/compose/.env.example に注釈があります

Console で端末を開いているセッションが止まらないのは、その端末に在席の猶予内の打鍵があるあいだだけです。

在席と数える 数えない
端末での打鍵とペースト 端末の自動応答(フォーカスの通知、デバイス属性やカーソル位置の応答、色の問い合わせへの応答)
表示中のブラウザペインでの最後のクリック・スクロール・キー入力・ペースト Console が開いたままの端末のペインを自動で接続し直すこと
タブを切り替えて、ペインがもう一度表示されたこと

打鍵しないまま開きっぱなしのタブや、画面ロックされずに前に出ているタブは、ワークスペースを引き止めません。

止まったワークスペースを起こすもの

Section titled “止まったワークスペースを起こすもの”

止まったワークスペースは、メンバーが「起動」を押せば戻ります。そのほかに、次の 2 つが自動で起こします。

仕組み 起こすとき
AF_AUTOSTART(既定でオン) 「今から使う」がはっきりした操作のときだけ。セッションの作成・fork・再開、持ち越した質問への回答、SSM のノードの探索です
テナントの サインイン時の自動起動(既定でオフ。サインインしたらワークスペースを起動する) 表示中のタブで、実際の操作があったあとか、サインインやアドレスの入力で着いた直後に 1 回だけ。再読み込みは数えません
  • 端末を開いても、閲覧しても、Console を再読み込みしても起動しません。止まっていることを返すだけです
  • AF_AUTOSTART=0 にすると、サインイン時の自動起動も無効になります
  • テナントのスイッチ、メンバーのオプトアウト、max_workspaces は Control Plane が確かめます

ワークスペースを起こし続けるもの

Section titled “ワークスペースを起こし続けるもの”
もの 起こし続ける時間
バックグラウンド作業(アイドルのセッションが起動した開発サーバーや run_in_background のタスク) バックグラウンド保持の上限まで。超えると、起こし続ける理由から外れます
「作業中」のターミナルのセッション 生きている兆候があるあいだだけ。「生存の兆候なし」の上限(製品として固定のもの)のあいだ何も変わらなければ、数えなくなります
「自動停止しない」ピン 上限なし。本当に長いジョブはこれで残します

「生存の兆候なし」の上限は、作業の合計時間ではなく、変化がない時間の上限です。何を生きている兆候とみなすかは、エージェントによって違います。

エージェント 生きている兆候
ターミナルの claude・agy 出力、状態の変化、実行中のツールのプロセス
ターミナルの codex・cursor・copilot・kiro・opencode ペインの描き直しだけ(スピナーや経過時間の更新を含む)
マネージドの cursor・kiro・codex・opencode そのセッションの最後のメッセージか、実行中のツール(終わっていないツールの呼び出し。cursor と kiro はランタイムの下のツールのプロセスも)
マネージドの lcpp ターンの実行中はずっと生きているとみなします。ターンが終わったあとに「作業中」のまま残った行だけが外れます
マネージドの muse・copilot 上限の対象外
  • ペインの描き直しだけを見るエージェントでは、出力しないツールでペインが止まったままだと外れることがあります。逆に、スピナーが回り続ける固まったセッションは抱え続けます。長い無出力の作業には「自動停止しない」ピンを使ってください
  • マネージドのセッションでは、外部の MCP サーバーへの長い呼び出しも、呼び出しのあいだずっと終わっていないものとして見えます(cursor ではまだ確かめていません)
  • Agent が何が動いているかを判断できないとき(再起動・再接続・プロセス表の読み取りの失敗)は、抱え続けます
  • shell と ssm は「作業中」になりません。muse と lcpp にはターミナルの実行方式がありません
  • バックグラウンド作業と「自動停止しない」ピンは、この上限の対象外です

起動中のまま起動の期限を超えたワークスペースは、止まります。ECS では、たいていクラスターがタスクを配置できないときです。容量を占有し続けないようにするためで、原因を直せばメンバーはもう一度「起動」を押せます。

  • 期限は最後の起動から数えます。Control Plane がそれより後に初めて起動中と見たとき(Control Plane の再起動後など)は、その時点から数えます
  • 判定は usage のサンプルごと(5 分)なので、止まるのは最大でサンプル 1 回分遅れます
  • メンバーには、通知センターに起動を止めた知らせが、最後の起動のフェーズ(ecs-ec2 ならタスクを配置できない理由)付きで届きます。テナント管理者にも、次の起動まで同じ理由が名簿の行とメンバー詳細に出ます。Control Plane のログには start-deadline: stopped … が残ります
設定 意味
AF_WORKSPACE_START_DEADLINE 期限。0 を指定すると無効になります。ecs-ec2 では、プール自身の起動の予算(AF_ECS_EC2_CLAIM_TTL_SEC・AF_ECS_EC2_WAIT_SEC)より短くなりません
AF_USAGE_SAMPLE_INTERVAL=0 usage サンプラーの上で動くので、これでも無効になります

動いているワークスペースの Agent が応答しなくなっても、止めずに印を付けるだけです。 ワークスペースのコンテナには ECS のヘルスチェックがなく、Agent が何をしていても ECS はタスクを running と報告します。それに気づくのがこの検知です。

  1. Control Plane は、Agent からの応答(Console のポーリング、リレー、usage サンプラー、ヘルスプローブ)をすべて記録します
  2. ランタイムが running と言っているのに、AF_AGENT_SILENT_AFTER のあいだ応答がないと、直接 /healthz を確かめます(ワークスペースごとに 30 秒に 1 回まで)
  3. その確認も失敗したときだけ、印が付きます
印が付くと 出る場所
メンバー 「応答なし」のバッジ
テナント管理者 メンバー詳細の表示と、障害 1 回につき 1 通の通知
記録 ログの agent silent: …、監査ログの workspace.agent_silent / workspace.agent_recovered
  • AF_AGENT_SILENT_AFTER の既定は 3m で、0 を指定すると無効になります。Control Plane が動いていると見てから一度も応答がないときは、その 2 倍待ちます
  • 状態は Control Plane のレプリカごとに持ち、レプリカが再起動すると猶予からやり直します。デプロイで一斉に警報が出ることはありません
  • 誰も開いていないワークスペースに届くのは usage サンプラーの巡回です。AF_USAGE_SAMPLE_INTERVAL=0 にすると、誰かがポーリングしているあいだの確認だけが残ります

AF_AGENT_SILENT_AFTER は Control Plane の環境でだけ設定できます。Compose は .env、Kubernetes(GKE も)は cp.env に書きます。ECS のテンプレートにはこのパラメータがないので、ECS では既定の 3m で動きます。

応答しない Agent を自動で止める

Section titled “応答しない Agent を自動で止める”

既定では無効です。AF_AGENT_SILENT_STOP_AFTER(30m のような Go の期間の書きかた)を設定すると、「応答なし」の印が付いたままその時間を過ぎたワークスペースを、Control Plane が止めます。

形態 設定する場所
ECS 30-ingress.yaml のパラメータ AgentSilentStopAfter
Docker Compose .env
Kubernetes(GKE も) ConfigMap af-cp-env の元になる cp.env
  • 時間は、そのレプリカが印を付けたときから数えます(再起動するとやり直し)
  • 10m より短くはなりません。小さい値はログに残して 10m にします。AF_AGENT_SILENT_AFTER が有効なことが前提です
  • 判定は usage サンプラーの巡回で行うので、ふつうは時間を過ぎてから AF_USAGE_SAMPLE_INTERVAL 以内に止まります。下の歯止めで見送ったとき、ライフサイクルのロックが使われているとき、巡回が最後まで終わらなかったときは、もっと遅れます
  • 管理者の停止と同じロック(メンバーの起動のロック、ライフサイクルのリース、ランタイムの操作のロック)を取り、そのうえで判断をやり直します
  • ワークスペースがまだ running であること(starting は対象外で、メンバー自身の再起動中も含みます)と、新しい /healthz の確認がもう一度失敗することを確かめます
  • 2 つのレプリカが同時に止めることはありません。あとから来た側は止まったと見て何もしません

Control Plane 自身が通信できなくなったときのための歯止めがあります。

  • 巡回が最後まで終わり、かつほかに応答した動いているワークスペースが 1 つ以上あるときだけ止めます
  • 1 回の巡回で止めるのは、最大 2 つ(応答がない時間が長い順)です
  • 動いているワークスペースが 1 つだけの配備では、印を付けるだけで止めません

止めると、監査ログに workspace.agent_silent_stop(actor は system)、ログに agent silent stop: … が残り、メンバーに通知が届き、次の起動までテナントの名簿に「自動で停止」と出ます。

ワークスペースを強制停止する

Section titled “ワークスペースを強制停止する”

docker compose down では、メンバーのワークスペースは止まりません。compose の管理外だからです。

したいこと 方法
特定のワークスペースを確実に止める 配備管理者が Console の管理画面から強制停止します(ワークスペースを強制停止する)
メンテナンスでホスト全体を落とす Control Plane と Caddy を止めたうえで、残った af-ws-* のコンテナを別に docker stop します(症状から原因を探す)

使わないあいだ配備を一時停止する

Section titled “使わないあいだ配備を一時停止する”

ワークスペースをすべて止めても、Control Plane・データベース・NAT ゲートウェイ・ロードバランサーの費用は残ります。 しばらく誰も使わないときは、AWS と GKE の配備の pause.sh で、時間で課金されるものを止めるか消します。データは残ります。--up で戻します。

オプション 意味
(--yes なし) 計画を表示するだけです
--dry-run 書き込みをせずに表示します
--status 動いているものと課金が続くものを表示するだけで、何も変えません
--keep-db データベースを動かしたままにします
--up 配備を戻します
形態 止めるもの 課金が続くもの
AWS(ecs / ecs-ec2):deploy/aws/ecs/pause.sh 動いているワークスペース(セッションは終わります)、スロットとエンジンの GPU マシン、Control Plane、RDS のインスタンス、NAT ゲートウェイ(--keep-nat で残します) ロードバランサー、EFS、データベースのストレージ
GKE(kubernetes):deploy/gcp/gke/pause.sh Control Plane(0 にします)、workspace と system のノードプール、Cloud SQL GKE の管理手数料、ロードバランサーの転送ルール、Private Service Connect のエンドポイント、Cloud NAT とそのアドレス、永続ディスク、Cloud SQL のストレージ

AWS で気をつけること:

  • NAT ゲートウェイは、ネットワークスタックのパラメータ NatEnabled で消します。手で消すと、スタックは消えたゲートウェイを指したままになります
  • 送信元のアドレスは残すので、--up のあとも送信元の IP は変わりません。ゲートウェイがないあいだ、プライベートサブネットからは外に出られません
  • AWS は、止めた RDS のインスタンスを 7 日後に自動で起動します。データスタックの再停止の仕組み(RdsRestopOnForcedStart、既定で有効)が、一時停止のタグが付いているあいだはもう一度止めます。古いデータスタックには、そのスタックを 1 回デプロイすると入ります
  • egress ゲートウェイ(EgressRoute=gateway)がある配備では、Control Plane より先にゲートウェイのインスタンスも止めます(アドレスは残します)。--up は、ゲートウェイが通信を通せるようになるまで待ちます
  • --up は NAT ゲートウェイ・データベース・Control Plane を戻します。ワークスペースはメンバーが自分で起動します
  • --fast を付けると、スロットとエンジンを Control Plane に眠らせず、直接止めます

GKE で気をつけること:

  • kubectl がそのクラスターを指しているシェルで実行します。コンテキストのサーバーと CA がそのクラスターのものでなければ、実行を拒みます
  • ワークスペースが動いていると拒みます。--stop-workspaces を付けると止めます
  • Cloud SQL は RDS と違い、自分で起動し直しません
  • ノード数は Control Plane の名前空間に記録し、--up で元に戻します。それまでのあいだ、terraform plan はノードプールの差分を報告します

それぞれのスクリプトが従う順番とその理由、終わったあとに確かめることは、手順書の ECS の「Lifecycle scripts」 と Kubernetes の「Pausing」 にあります。

費用をできるだけ 0 に近づけたいときは、配備を削除します(AWS は teardown.sh、GKE は terraform destroy)。何が残るかは形態によって違います。

形態 削除のあとに残るもの
AWS で Persistence=retain --purge-retained を付けない限り、データベースの最後のスナップショット、EFS のファイルシステムとそのバックアップボールト(ストレージの費用は続きます)
GKE Control Plane のディスクのスナップショット。先に削除保護を外す必要があります

何が消えて何が残るかは、手順書の ECS の「Teardown」 と Kubernetes の「Tearing down」 にあります。

エージェント向け

この指示をエージェントに送ると、このページを読ませられます。

https://agent-fleet.org/docs/ja/operate/run/idle-stop/index.md を読んで