Skip to content
Merged
Changes from 3 commits
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
49 changes: 48 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,55 @@ 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. Instances in the `waiting` state are excluded from 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.

For example, consider a Workflow that does some work, waits for 30 days, and then continues with more work:

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

type Env = {
MY_WORKFLOW: Workflow;
};

export class MyWorkflow extends WorkflowEntrypoint<Env> {
async run(event: WorkflowEvent<unknown>, step: WorkflowStep) {

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',
{
retries: {
limit: 5,
delay: '5 second',
backoff: 'exponential',
},
timeout: '15 minutes',
},
async () => {
if (Math.random() > 0.5) {
throw new Error('API call to $STORAGE_SYSTEM failed');
}
},
);
}
}
```

While a given Workflow instance is waiting for 30 days, it will transition to the `waiting` state, allowing other `queued` instances to run if concurrency limits are reached.

### 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