OpenAICloudflare Developer PlatformMay 1, 2026, 12:00 AM

Workflows, Workers - Run Workflows inside Dynamic Workers with the @cloudflare/dynamic-workflows library

A condensed section focused on the key takeaways first.

Original Post

Quick Digest

Summary

A condensed section focused on the key takeaways first.

openaienmodel: gpt-5-mini-2025-08-07

Run Workflows inside Dynamic Workers with @cloudflare/dynamic-workflows

Key Points

  • Durable Workflows in Dynamic Workers
  • Worker Loader reloads matching worker on wake
  • wrapWorkflowBinding tags instances with tenant metadata

Summary

The @cloudflare/dynamic-workflows library lets you run Workflows inside Dynamic Workers and preserve durable execution even when Dynamic Worker code is loaded on demand and evicted from memory. Each Workflow instance is tagged with metadata (for example, tenantId) so the Worker Loader can reload the correct Dynamic Worker when the Workflow wakes after long sleeps or restarts. The Workflows engine continues to handle persistence, retries, and normal Workflow semantics; you only need to load tenant code on demand and wrap the Workflows binding with identifying metadata.

Key Points

  • Durable Workflows inside Dynamic Workers: Workflow instances include metadata used to reload the matching Dynamic Worker via the Worker Loader when a Workflow resumes.
  • No upfront registration: Dynamic Workers and Workflow code can be loaded on demand (per-tenant or per-agent) — you don’t need to register every Workflow ahead of time.
  • Integration pattern (TypeScript): use LOADER.get(tenantId, ...) to create the Dynamic Worker with env.WORKFLOWS set to wrapWorkflowBinding({ tenantId }).
  • Entrypoint requirements: the createDynamicWorkflowEntrypoint entrypoint name must match class_name in your Wrangler workflows binding.
  • Failover & retries: the Workflows engine continues to persist state and retry steps; your Workflow code is unchanged by the routing layer.
  • Common use cases: per-tenant automations (SaaS), AI agent multi-step plans, multi-tenant job processing with per-customer logic.

Quick Integration Notes

  • Use createDynamicWorkflowEntrypoint to return a WorkflowRunner that loads the tenant-specific entrypoint via the loader stub.
  • Wrap the binding with wrapWorkflowBinding({ tenantId }) so every create() call is tagged and can be routed back to the tenant Dynamic Worker.
  • Typical fetch handler: read x-tenant-id, call loadTenant(env, tenantId).getEntrypoint().fetch(request).

For a full walkthrough, follow the Dynamic Workflows guide linked in the release post.

Full Translation

Translations

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

openaijamodel: gpt-5-mini-2025-08-07

Workflows、Workers — @cloudflare/dynamic-workflows ライブラリで Dynamic Workers 内で Workflows を実行する

公開日: 2026-05-01

Workflows、Workers — @cloudflare/dynamic-workflows ライブラリで Dynamic Workers 内で Workflows を実行する

@cloudflare/dynamic-workflows ↗ を使って、ランタイムでロードされるコードに対しても耐久性のある実行を保証しつつ、Dynamic Worker の内部で Workflow を実行できるようになりました。

Worker Loader は Dynamic Worker をオンデマンドでロードするため、これまでは耐久性の確保が困難でした。Dynamic Worker 内の Workflow はステップ間で数時間または数日間スリープする可能性があり、再開時には元の Dynamic Worker コードがメモリ上に存在しないことがあります。

このライブラリは、各 Workflow インスタンスにどの Dynamic Worker をロードするかを識別するメタデータ(例えば tenant ID)をタグ付けし、Workflow が再開するたびに Worker Loader を通して該当する Dynamic Worker を再ロードすることでこの問題を解決します。Dynamic Workers はオンデマンドで作成されるため、各 Workflow を事前に登録したり個別に管理したりする必要はありません。必要なときに Dynamic Worker 内で Workflow コードをロードし、Workflows エンジンが永続化やリトライを裏側で処理します。Workflow コード自体にルーティングのための変更は不要で、通常どおり動作します。

これにより、Workflow コード自体が動的であるパターンが可能になります。例えば次のようなユースケースで有用です:

  • SaaS プラットフォーム: 各テナントがオンボーディングシーケンス、承認チェーン、課金のリトライロジックなど独自のオートメーションを定義するケース。
  • AI エージェントフレームワーク: エージェントが実行時にマルチステップの計画を生成・実行し、ツール呼び出しの間に人間の承認を待つなど、再起動や待機をまたいで継続するケース。
  • マルチテナントのジョブシステム: 各顧客が独自の処理ロジックを提出し、各ステップが進捗を永続化して失敗時にリトライするケース。

使用例 (TypeScript)

以下は @cloudflare/dynamic-workflows を使って、テナントごとにコードをロードして Workflow を実行する例です。

import { createDynamicWorkflowEntrypoint, DynamicWorkflowBinding, wrapWorkflowBinding, type WorkflowRunner, } from "@cloudflare/dynamic-workflows";
export { DynamicWorkflowBinding };
interface Env { WORKFLOWS: Workflow; LOADER: WorkerLoader; }
function loadTenant(env: Env, tenantId: string) {
    return env.LOADER.get(tenantId, async () => ({
        compatibilityDate: "2026-01-01",
        mainModule: "index.js",
        modules: { "index.js": await fetchTenantCode(tenantId) },
        // The Dynamic Worker uses this exactly like a real Workflow binding;
        // every create() is tagged with { tenantId } automatically.
        env: { WORKFLOWS: wrapWorkflowBinding({ tenantId }) },
    }));
}
// The entrypoint name must match `class_name` in the workflows binding of your Wrangler config file.
export const DynamicWorkflow = createDynamicWorkflowEntrypoint<Env>(
    async ({ env, metadata }) => {
        const stub = loadTenant(env, metadata.tenantId as string);
        return stub.getEntrypoint("TenantWorkflow") as unknown as WorkflowRunner;
    },
);
export default {
    fetch(request: Request, env: Env) {
        const tenantId = request.headers.get("x-tenant-id")!;
        return loadTenant(env, tenantId).getEntrypoint().fetch(request);
    },
};

注: 上記の例では、Dynamic Worker の構成で Workflows バインディングの class_name とエントリポイント名が一致する必要があります。

詳細とリソース

詳細なウォークスルーについては Dynamic Workflows guide を参照してください。