Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion src/content/docs/workflows/reference/limits.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Many limits are inherited from those applied to Workers scripts and as documente
| Maximum `step.sleep` duration | 365 days (1 year) | 365 days (1 year) |
| Maximum steps per Workflow [^5] | 1024 | 1024 |
| Maximum Workflow executions | 100,000 per day [shared with Workers daily limit](/workers/platform/limits/#worker-limits) | Unlimited |
| Concurrent Workflow instances (executions) per account | 25 | 10,000 |
| Concurrent Workflow instances (executions) per account [^7] | 25 | 10,000 |
| Maximum Workflow instance creation rate | 100 per second [^6] | 100 per second [^6] |
| Maximum number of [queued instances](/workflows/observability/metrics-analytics/#event-types) | 10,000 | 100,000 |
| Retention limit for completed Workflow state | 3 days | 30 days [^2] |
Expand All @@ -42,8 +42,65 @@ Many limits are inherited from those applied to Workers scripts and as documente

[^6]: Workflows will return a HTTP 429 rate limited error if you exceed the rate of new Workflow instance creation.

[^7]: Only instances with a `running` state count towards the concurrency limits. If an instance is in a `waiting` state it does not count these limits.

<Render file="limits_increase" product="workers" />

### `waiting` instances do not count towards instance concurrency limits

Instances that are on a `waiting` state - either sleeping, waiting for a retry or waiting for an event - do **not** count towards concurrency limits. It means that other `queued` instances will be scheduled when an instance goes from a `running` state to a `waiting` one, usually the oldest instance queued, in a best-effort basis. This state transition - `running` to `waiting` - might not happen if the duration of the wait is too short.

As an example, let's say we have a workflow that does some work, waits 30 days, and continues other work:

```ts title="src/index.ts"
import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent } from 'cloudflare:workers';

type Env = {
// Add your bindings here, e.g. Workers KV, D1, Workers AI, etc.
MY_WORKFLOW: Workflow;
};

// User-defined params passed to your workflow
type Params = {
email: string;
metadata: Record<string, string>;
};

export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
// Can access bindings on `this.env`
// Can access params on `event.payload`
const apiResponse = await step.do('initial work', async () => {
let resp = await fetch('https://api.cloudflare.com/client/v4/ips');
return await resp.json<any>();
});

await step.sleep('wait 30 days', '30 days');

await step.do(
'make a call to write that could maybe, just might, fail',
// Define a retry strategy
{
retries: {
limit: 5,
delay: '5 second',
backoff: 'exponential',
},
timeout: '15 minutes',
},
async () => {
// Do stuff here, with access to the state from our previous steps
if (Math.random() > 0.5) {
throw new Error('API call to $STORAGE_SYSTEM failed');
}
},
);
}
}
```

While a given Workflow instance is waiting for 30 days to pass, it will go to a `waiting` state, allowing other `queued` instances to run - if concurrency limits are exhausted.

### Increasing Workflow CPU limits

Workflows are Worker scripts, and share the same [per invocation CPU limits](/workers/platform/limits/#worker-limits) as any Workers do. Note that CPU time is active processing time: not time spent waiting on network requests, storage calls, or other general I/O, which don't count towards your CPU time or Workflows compute consumption.
Expand Down
Loading