ClaudeCloudflareApr 15, 2026, 1:00 PM

Rearchitecting the Workflows control plane for the agentic era

A condensed section focused on the key takeaways first.

Original Post

Quick Digest

Summary

A condensed section focused on the key takeaways first.

claudeenmodel: claude-haiku-4-5

Workflows Control Plane V2: Scaling to 50,000 Concurrent Instances

Key Points

  • 50,000 concurrent instances support (10x increase)
  • Horizontally scalable SousChef and Gatekeeper components
  • Zero-downtime migration from V1 to V2 architecture

Summary

Cloudflare has rearchitected the Workflows control plane to support agent-driven workloads at machine speed. The shift from human-triggered to agent-triggered workflows required a complete redesign to handle dramatically higher throughput and concurrency demands.

Key Improvements

  • 50x concurrency increase: From 4,500 to 50,000 concurrent instances
  • 3x creation rate increase: From 100 to 300 instances/second per account
  • 2M queued instances: Support for 2 million queued instances per workflow (up from 1 million)

V2 Architecture Changes

The new control plane introduces two critical components:

  • SousChef: A "second in command" that manages metadata and lifecycle for workflow subsets, enabling per-workflow isolation and distributed load
  • Gatekeeper: A leasing system that distributes concurrency slots across SousChefs, batching requests once per second to prevent Account overload

Technical Highlights

  • Engine is now the single source of truth for instance existence
  • Instance creation path optimized: check version → fetch workflow metadata → store to Engine
  • Background tasks and alarms remove operations from hot-path while maintaining reliability
  • Instance listing now supports cursor pagination with improved performance
  • All instance operations execute in a single network hop

Migration Strategy

Existing V1 Accounts were converted to SousChef DOs in-place, maintaining instance metadata while adding new functionality without downtime or disruption.

Full Translation

Translations

A translation section that keeps the flow of the original article.

claudejamodel: claude-haiku-4-5

エージェント時代に向けたWorkflows制御プレーンの再設計

エージェント時代に向けたWorkflows制御プレーンの再設計

2026-04-15 Luís Duarte Mia Malden André Venceslau 8分で読める

概要

Workflowsを最初に構築した際、マルチステップアプリケーション用の耐久実行エンジンは、ユーザーのサインアップや注文など、人間のアクションによってワークフローがトリガーされる世界を想定していました。オンボーディングフローのようなユースケースでは、ワークフローは1人あたり1つのインスタンスのみをサポートすればよく、人間がクリックできる速度には限界があります。

しかし実際には、ワークロードとアクセスパターンに定量的な変化が見られました。人間がトリガーするワークフローは減少し、マシン速度で作成されるエージェントがトリガーするワークフローが増加しています。

エージェント駆動型ワークフローへの移行

エージェントが永続的で自律的なインフラストラクチャとなり、数時間から数日間ユーザーに代わって動作するにつれて、実行する作業のための耐久的で非同期の実行エンジンが必要になります。Workflowsはまさにそれを提供します。

  • 各ステップは独立して再試行可能
  • ワークフローは人間によるループ承認のために一時停止可能
  • 各インスタンスは障害を乗り越えて進捗を失わない

さらに、ワークフロー自体がエージェントループの実装に使用され、エージェントを管理して生存させる耐久的なハーネスとして機能しています。Agents SDK統合により、エージェントがワークフローインスタンスを簡単にスポーンし、リアルタイムの進捗を取得できるようになりました。

単一のエージェントセッションで数十のワークフローをキックオフでき、複数のエージェントが同時に実行されると、数秒で数千のインスタンスが作成されます。Project Thinkが利用可能になったため、この速度はさらに増加すると予想されます。

スケーラビリティの向上

Workflows上でエージェントとアプリケーションをスケーリングするのを支援するため、以下のサポートを発表します。

  • 50,000の同時インスタンス(並行して実行されているワークフロー実行の数)- 元々は4,500
  • アカウントあたり300インスタンス/秒の作成 - 以前は100
  • ワークフローあたり200万のキューに入ったインスタンス(作成または起動され、同時実行スロットを待機しているインスタンス)- 100万から増加

V1: Workflows制御プレーンの初期アーキテクチャ

Workflowsは当社独自の開発者プラットフォーム上に完全に構築されました。基本的に、ワークフローは一連の耐久ステップであり、各ステップは独立して再試行可能で、タスクを実行したり、外部イベントを待機したり、所定の時間まで休止したりできます。

export class MyWorkflow extends WorkflowEntrypoint {
  async run(event, step) {
    const data = await step.do("fetch-data", async () => {
      return fetchFromAPI();
    });
    const approval = await step.waitForEvent("approval", {
      type: "approval",
      timeout: "24 hours",
    });
    await step.do("process-and-save", async () => {
      return store(transform(data));
    });
  }
}

各インスタンスをトリガーし、そのロジックを実行し、メタデータを保存するために、SQLiteバックアップのDurable Objectsを活用しました。これは分散システム内での調整とストレージのためのシンプルながら強力なプリミティブです。

制御プレーンでは、一部のDurable Objects(実際のワークフローインスタンスを実行するEngineなど)は1:1の比率でインスタンスごとにスピンアップされます。一方、AccountはアカウントレベルのDurable Objectで、そのアカウントのすべてのワークフローとワークフローインスタンスを管理します。

V1の制限

Workflowsをベータ版で立ち上げた後、顧客が急速に製品の使用をスケーリングしているのを見て喜びましたが、すべてのアカウントレベル情報を保存する単一のDurable Objectがボトルネックを引き起こしていることに気付きました。

多くの顧客は1分あたり数百から数千のワークフローインスタンスを作成および実行する必要があり、これは元のアーキテクチャのAccountを圧倒する可能性がありました。元のレート制限(4,500同時実行スロットと10秒あたり100インスタンス作成)はこの制限の結果でした。

V1制御プレーンでは、これらの制限はハードキャップでした。Accountに依存するすべての操作(作成、更新、リスト)は、その単一のDOを通過する必要がありました。高同時実行ワークロードを持つユーザーは、任意の時点で数千のインスタンスが開始および終了し、Accountへの毎秒数千のリクエストに蓄積される可能性がありました。

V2: より高いスループットのための水平スケーリング

新しいバージョンでは、高ボリュームワークフローに最適化することを目標に、すべての単一操作を一から再考しました。最終的に、Workflowsは開発者が必要とするもの(毎秒数千のインスタンス作成または同時に実行される数百万のインスタンス)をサポートするようにスケーリングする必要があります。

また、V2がハードキャップを課すV1制限ではなく、柔軟な制限を許可し、切り替えて継続的に増加させることができることを確認したいと考えました。

多くの設計反復の後、新しいアーキテクチャの以下の柱に落ち着きました。

アーキテクチャの原則

  • 特定のインスタンスの存在の真実のソースはそのEngineであり、他には何もない
  • インスタンスライフサイクルと生存メカニズムは、ワークフローごとに水平スケーラブルで、多くのリージョン全体に分散している必要がある
  • 新しいAccountシングルトンは最小限の必要なメタデータのみを保存し、同時リクエストの不変最大値を持つ必要がある

V2制御プレーンの新しいコンポーネント

V2制御プレーンのスケーラビリティを向上させることができた2つの新しい重要なコンポーネントがあります。

SousChef

SousChefは、Accountの「副官」です。以前は、Accountは特定のアカウント内のすべてのワークフロー全体のすべてのインスタンスのメタデータとライフサイクルを管理していました。SousChefは、特定のワークフロー内のインスタンスのサブセットのメタデータとライフサイクルを追跡するために導入されました。

アカウント内では、SousChefの分布がより効率的で管理可能な方法でAccountに報告できます。このデザインの追加の利点として、既にアカウントごとの分離がありましたが、各SousChefが1つの特定のワークフローのみを処理するため、同じアカウント内で「ワークフローごと」の分離も無意識に得られました。

Gatekeeper

Gatekeeperは、同時実行「スロット」(同時実行制限から派生)をアカウント内のすべてのSousChef全体に分散するメカニズムです。リーシングシステムとして機能します。

インスタンスが作成されると、そのアカウント内のSousChefの1つにランダムに割り当てられます。その後、SousChefはAccountにリクエストを送信してそのインスタンスをトリガーします。スロットが付与されるか、インスタンスがキューに入ります。スロットが付与されると、SousChefはインスタンスの実行をトリガーし、インスタンスが決してスタックしないという責任を引き受けます。

Gatekeeperは、Engineが決してAccountをオーバーロードしないようにするために必要でした(V1での差し迫ったリスク)。そのため、SousChefとそのAccount間のすべての通信は定期的なサイクルで発生し、1秒に1回です。各サイクルはすべてのスロットリクエストもバッチ処理し、1つのJSRPCコールのみが行われることを保証します。

これにより、インスタンス作成レートが最も重要なコンポーネントであるAccountをオーバーロードまたは影響を与えることはできません。(余談ですが、SousChefカウントが高すぎる場合、呼び出しをレート制限するか、異なる時間帯に異なるSousChef全体に分散させます)。

また、この定期的なプロパティにより、古いインスタンスの公平性を保持し、多くのSousChef全体でmax-min公平性を確保でき、すべてが進行できるようになります。たとえば、インスタンスが起動する場合、新しく作成されたインスタンスよりもスロットの優先順位を付ける必要がありますが、各SousChefは独自のインスタンスがスタックしないようにします。

インスタンス作成フロー

このアーキテクチャはより分散しており、したがってより拡張可能です。インスタンスが作成されると、リクエストパスは次のようになります。

  1. 制御プレーンバージョンを確認
  2. ワークフローとバージョン詳細のキャッシュされたバージョンがその場所で利用可能かどうかを確認
  3. 利用できない場合は、Accountをチェックしてワークフロー名、一意のID、バージョンを取得し、その情報をキャッシュ
  4. 必要なメタデータのみ(インスタンスペイロード、作成日)を独自のEngineに保存

Engineが制御プレーンに存在することをどのように伝えるのでしょうか?それはインスタンスメタデータが設定された後、バックグラウンドで発生します。Durable Objectのバックグラウンド操作は、削除またはサーバー障害により失敗する可能性があるため、作成ホットパスでEngineに「アラーム」も設定します。

バックグラウンドタスクが完了しない場合、アラームはインスタンスが開始されることを保証します。Durable Objectアラームにより、Durable Objectインスタンスは将来の細粒度の時間に起動され、少なくとも1回の実行モデルで、自動再試行が組み込まれています。

ホットパスから操作を削除しながら、すべてが計画通りに実行されることを確認するために、バックグラウンド「タスク」とアラームのこの組み合わせを広範に使用します。これにより、インスタンスの作成などの重要な操作を高速に保ちながら、信頼性を決して損なわないようにします。

V2の利点

スケールのロック解除以外に、この制御プレーンのバージョンは以下を意味します。

  • インスタンスリスティングのパフォーマンスが高速化され、カーソルページネーションと実際に一貫性がある
  • インスタンスの任意の操作は正確に1つのネットワークホップを実行します(そのEngineに直接移動できるため、眼球リクエストレイテンシーを可能な限り小さく保証します)
  • より多くのインスタンスが実際に正しく動作していることを確認できます(定時に実行され、正しくない場合は修正し、Engineが実行を続行するのに遅れないようにします)

V1からV2への移行

より高いボリュームのユーザーロードを処理できるWorkflows制御プレーンの新しいバージョンができたので、「退屈な」部分を実行する必要がありました。顧客とインスタンスを新しいシステムに移行することです。

Cloudflareのスケールでは、これ自体が問題になるため、「退屈な」部分が最大の課題になります。1年のマークをはるか前に、Workflowsは既に数百万のインスタンスと数千の顧客を蓄積していました。

また、V1の制御プレーンのいくつかの技術的負債は、キューに入ったインスタンスが独自のEngine Durable Objectをまだ作成していない可能性があることを意味し、事態をさらに複雑にしました。

顧客は任意の時点でインスタンスを実行している可能性があるため、この移行は難しいです。SousChefおよびGatekeeperコンポーネントを古いアカウントに追加する方法が必要でしたが、中断やダウンタイムは発生しませんでした。

最終的に、既存のAccounts(AccountOldsと呼びます)をSousChefのように動作するように移行することを決定しました。Account DOsを永続化することで、インスタンスメタデータを保持し、DOをSousChef「DO」に単純に変換しました。

// SousChefクラスが何かと思っているかもしれません。これはSousChef DOクラスです!
import { SousChef } from "@repo/souschef";

class AccountOld extends DurableObject {
  constructor(state: DurableObjectState, env: Env) {
    // AccountOld DOのコンストラクタの最後に次のスニペットを追加しました。
    // これにより、必要に応じて、SousChef DOで利用可能なプリミティブを使用できます
    if (this.currentVersion === ControlPlaneVersions.SOUS_CHEFS) {
      this.sousChef = new SousChef(this.ctx, this.env);
      await this.sousChef.setup()
    }
  }

  async updateInstance(params: UpdateInstanceParams) {
    if (this.currentVersion === ControlPlaneVersions.SOUS_CHEFS) {
      assert(this.sousChef !== undefined, 'SousChef must exist on v2');
      return this.sousChef.updateInstance(params);
    }
    // old logic remains the same
  }

  @RequiresVersion<AccountOld>(ControlPlaneVersions.V
}
Rearchitecting the Workflows control plane for the agentic era | Cloudflare | DocsDigest