---
title: "Cloudflare Workflows - Durable Execution Engine"
description: "Build durable workflows & multi-step applications. Execution engine built on Cloudflare Workers with automatic retry, state persistence, and long-running support."
url: "https://www.cloudflare.com/products/workflows"
---

# Workflows

> Workflows is an execution engine built on Cloudflare Workers — to build applications that can automatically retry, persist state and run for minutes, hours, days, or weeks. No need to worry about scaling, managing infrastructure, or handling durability: Workflows takes care of it for you.

## Key Features

- Automatic retries
- State persistence
- Step-based execution
- Long-running support
- Human-in-the-loop
- Event-driven triggers
- Pay per compute time

## Benefits

### Step-based

Any logic wrapped in a step can be automatically retried and memoized for durability, without extra boilerplate or checkpoints.

### State included

Every instance persists to its own local state: no need to set up or manage a database or control plane.

### Human-in-the-loop

Wait on external events: webhooks, approvals, queue messages — and use them to determine the next steps in your Workflow.

## Use Cases

### Building AI agents

Code review tasks, compact context, or processing data

### Asynchronous tasks

Lifecycle emails, billing jobs, and critical data processing tasks

### Post-processing user-generated content

Run inference, clean up or validate uploaded content

## Code Examples

### Step-by-step: Break your application down into discrete steps

Break your application down into discrete steps that can be retried, persist returned state, and replayed automatically.

```typescript
export class CheckoutWorkflow extends WorkflowEntrypoint {
  async run(event, step) {
    const processorResponse = await step.do('submit payment', async () => {
      let resp = await submitToPaymentProcessor(event.params.payment);
      return await resp.json<any>();
    });

    const textResponse = await step.do('send confirmation text', sendConfirmation);

    await step.sleep('wait for feedback', '2 days');

    await step.do('send feedback email', sendFeedbackEmail);

    await step.sleep('delay before marketing', '30 days');

    await step.do('send marketing follow up', sendFollowUp);
  }
}
```

### It's just code

Workflows, like Workers, are just code. Import the libraries you want and get to shipping.

```typescript
import { listR2Files } from './listR2Files';

interface Env {
  CHUNKS_BUCKET: R2Bucket;
  CHUNK_PROCESSOR: DurableObjectNamespace;
}
type Params = { instanceId: string };

export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
  async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
    const listResult = await listR2Files(this.env, event.instanceId, step);

    // Process each file from R2
    for (const key of listResult.keys) {
      await step.do("process file: " + key, async () => {
        return await doSomething(key, this.env.CHUNKS_BUCKET, event.instanceId);
      });
    }

    await step.do("restart workflow", async () => {
      if (listResult.truncated) {
        // There are still chunks to process
        const instance = await this.env.CHUNK_PROCESSOR.get(event.instanceId);
        await instance.restart();
      } else {
        // Reset the cursor for determinism on re-runs
        await this.env.CHUNKS_BUCKET.delete("cursor/" + event.instanceId);
        return "was not truncated, done";
      }
    });
  }
}
```

### Call Workflows from the Agents SDK

Use Workflows to enable agents to run background tasks as part of the Agents SDK:

```typescript
interface Env {
  MY_WORKFLOW: Workflow;
  MyAgent: AgentNamespace<MyAgent>;
}

export class MyAgent extends Agent<Env> {
  async onRequest(request: Request) {
    let userId = request.headers.get("user-id");
    // Trigger a schedule that runs a Workflow
    // Pass it a payload
    let { id: taskId } = await this.schedule(300, "runWorkflow", {
      id: userId,
      flight: "DL264",
      date: "2025-02-23"
    });
  }

  async runWorkflow(data) {
    let instance = await this.env.MY_WORKFLOW.create({
      id: data.id,
      params: data,
    });

    // Schedule another task that checks the Workflow status every 5 minutes...
    await this.schedule("*/5 * * * *", "checkWorkflowStatus", { id: instance.id });
  }
}

export class MyWorkflow extends WorkflowEntrypoint<Env> {
  async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
    // Your Workflow code here
  }
}
```

## Resources

- [Full Documentation](https://developers.cloudflare.com/workflows): Complete technical documentation
- [Get Started](https://dash.cloudflare.com/sign-up): Sign up and start building
- [Pricing](/plans.md): See pricing details

## Related Products

- [Browser Run](/products/browser-rendering.md): Automated browsers
- [Cloudflare Pages](/products/pages.md): Build & deploy frontend sites
- [Containers](/products/containers.md): Any language, anywhere
- [Durable Objects](/products/durable-objects.md): Stateful compute

---

*This is a markdown version of [https://www.cloudflare.com/products/workflows](https://www.cloudflare.com/products/workflows) for AI/LLM consumption.*
