You can now use @cloudflare/dynamic-workflows to run a Workflow inside a Dynamic Worker, ensuring durable execution for code that is loaded at runtime.
The Worker Loader loads Dynamic Workers on demand, which previously made durability challenging. Even within a Dynamic Worker, a Workflow might sleep for hours or days between steps, and by the time it resumes, the original Dynamic Worker code would no longer be in memory.
The library solves this by tagging each Workflow instance with metadata that identifies which Dynamic Worker to load — for example, a tenant ID — then reloading the matching Dynamic Worker through the Worker Loader whenever a Workflow awakens.
Because Dynamic Workers are created on-demand, you do not have to register each Workflow up front or manage them individually. Load the Workflow code in the Dynamic Worker when it is needed, and the Workflows engine handles persistence and retries behind the scenes. Your Workflow code itself is unaffected by the routing and behaves as normal.
This unlocks patterns where the Workflow code itself is dynamic. For example, this is useful with:
- SaaS platforms where each tenant defines their own automation, such as onboarding sequences, approval chains, or billing retry logic.
- AI agent frameworks where agents generate and execute multi-step plans at runtime, surviving restarts and waiting for human approval between tool calls.
- Multi-tenant job systems where each customer submits their own processing logic and every step persists progress and retries on failure.
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); },};For a full walkthrough, refer to the Dynamic Workflows example.
Source: Cloudflare
Latest Posts
- Workflows, Workers – Run Workflows inside Dynamic Workers with the @cloudflare/dynamic-workflows library

- Power Platform – Enable Managed Environment to extend storage retention period [MC1297538]
![Power Platform – Enable Managed Environment to extend storage retention period [MC1297538] 3 pexels googledeepmind 18068767](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==)
- GCP Release Notes: April 30, 2026

- Updates available for Microsoft 365 Apps for Current Channel [MC1297137]
![Updates available for Microsoft 365 Apps for Current Channel [MC1297137] 5 pexels ken tomita 127057 389818](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==)


![Power Platform – Enable Managed Environment to extend storage retention period [MC1297538] 3 pexels googledeepmind 18068767](https://mwpro.co.uk/wp-content/uploads/2025/06/pexels-googledeepmind-18068767-150x150.webp)

![Updates available for Microsoft 365 Apps for Current Channel [MC1297137] 5 pexels ken tomita 127057 389818](https://mwpro.co.uk/wp-content/uploads/2025/06/pexels-ken-tomita-127057-389818-150x150.webp)