diff --git a/src/content/changelog/workflows/2026-03-03-step-limits-to-25k.mdx b/src/content/changelog/workflows/2026-03-03-step-limits-to-25k.mdx new file mode 100644 index 00000000000..66636419651 --- /dev/null +++ b/src/content/changelog/workflows/2026-03-03-step-limits-to-25k.mdx @@ -0,0 +1,29 @@ +--- +title: Workflows step limit increased to 25,000 steps per instance +description: Each Workflow instance supports 10,000 steps by default, configurable up to 25,000 steps +products: + - workflows + - workers +date: 2026-03-03 12:00:00 UTC +--- + +Each Workflow instance now supports 10,000 steps by default, configurable up to 25,000 steps in your `wrangler.jsonc` file: + +```json +{ + "workflows": [ + { + "name": "my-workflow", + "binding": "MY_WORKFLOW", + "class_name": "MyWorkflow", + "limits": { + "steps": 25000 + } + } + ] +} +``` + +Previously, each instance was limited to 1,024 steps. Now, Workflows can support more complex, long-running executions without the additional complexity of recursive or child workflow calls. + +Note that the maximum persisted state limit per Workflow instance remains **100 MB** for Workers Free and **1 GB** for Workers Paid. Refer to [Workflows limits](/workflows/reference/limits/) for more information. diff --git a/src/content/docs/agents/api-reference/run-workflows.mdx b/src/content/docs/agents/api-reference/run-workflows.mdx index 11fb316eccd..669935e3936 100644 --- a/src/content/docs/agents/api-reference/run-workflows.mdx +++ b/src/content/docs/agents/api-reference/run-workflows.mdx @@ -825,12 +825,12 @@ await this.rejectWorkflow(instanceId, { reason: "Request denied" }); ## Limitations -| Constraint | Limit | -| ------------------- | ------------------- | -| Maximum steps | 1,024 per workflow | -| State size | 10 MB per workflow | -| Event wait time | 1 year maximum | -| Step execution time | 30 minutes per step | +| Constraint | Limit | +| ------------------- | --------------------------------------------------------- | +| Maximum steps | 10,000 per workflow (default) / configurable up to 25,000 | +| State size | 10 MB per workflow | +| Event wait time | 1 year maximum | +| Step execution time | 30 minutes per step | Workflows cannot open WebSocket connections directly. Use `broadcastToClients()` to communicate with connected clients through the Agent. diff --git a/src/content/docs/workflows/build/workers-api.mdx b/src/content/docs/workflows/build/workers-api.mdx index 1d81d7f2278..465399703d0 100644 --- a/src/content/docs/workflows/build/workers-api.mdx +++ b/src/content/docs/workflows/build/workers-api.mdx @@ -112,9 +112,13 @@ More information about the limits imposed on Workflow can be found in the [Workf ::: -- step.waitForEvent(name: string, options: ): Promise<void> - - `name` - the name of the step. - - `options` - an object with properties for `type` (up to 100 characters [^1]), which determines which event type this `waitForEvent` call will match on when calling `instance.sendEvent`, and an optional `timeout` property, which defines how long the `waitForEvent` call will block for before throwing a timeout exception. The default timeout is 24 hours. +- step.waitForEvent(name: string, options: ): Promise<void>- + `name` - the name of the step. - `options` - an object with properties for + `type` (up to 100 characters [^1]), which determines which event type this + `waitForEvent` call will match on when calling `instance.sendEvent`, and an + optional `timeout` property, which defines how long the `waitForEvent` call + will block for before throwing a timeout exception. The default timeout is 24 + hours. @@ -152,6 +156,28 @@ export type WorkflowStepConfig = { Refer to the [documentation on sleeping and retrying](/workflows/build/sleeping-and-retrying/) to learn more about how Workflows are retried. +## Workflow step limits + +Each workflow instance supports 10,000 steps by default. You can increase this up to 25,000 steps by configuring `steps` within the `limits` property of your Workflow definition in your Wrangler configuration: + + + +```toml +[[workflows]] +name = "my-workflow" +binding = "MY_WORKFLOW" +class_name = "MyWorkflow" + +[workflows.limits] +steps = 25_000 +``` + + + +Note that `step.sleep` does not count towards the maximum steps limit. + +Refer to [Workflow limits](/workflows/reference/limits/) for more information. + ## NonRetryableError {/* prettier-ignore */} @@ -182,9 +208,9 @@ For example, to bind to a Workflow called `workflows-starter` and to make it ava // binding name env.MY_WORKFLOW "binding": "MY_WORKFLOW", // this is class that extends the Workflow class in src/index.ts - "class_name": "MyWorkflow" - } - ] + "class_name": "MyWorkflow", + }, + ], } ``` @@ -220,9 +246,9 @@ For example, if your Workflow is defined in a Worker script named `billing-worke "class_name": "MyWorkflow", // the script name where the Workflow is defined. // required if the Workflow is defined in another script. - "script_name": "billing-worker" - } - ] + "script_name": "billing-worker", + }, + ], } ``` @@ -455,8 +481,10 @@ Terminate a Workflow instance. [Send an event](/workflows/build/events-and-parameters/) to a running Workflow instance. -- sendEvent(): Promise<void> - - `options` - the event `type` (up to 100 characters [^1]) and `payload` to send to the Workflow instance. The `type` must match the `type` in the corresponding `waitForEvent` call in your Workflow. +- sendEvent(): Promise<void>- `options` - the event `type` + (up to 100 characters [^1]) and `payload` to send to the Workflow instance. + The `type` must match the `type` in the corresponding `waitForEvent` call in + your Workflow. Return `void` on success; throws an exception if the Workflow is not running or is an errored state. @@ -505,9 +533,9 @@ type InstanceStatus = { | "waiting" // instance is hibernating and waiting for sleep or event to finish | "waitingForPause" // instance is finishing the current work to pause | "unknown"; - error?: { - name: string, - message: string + error?: { + name: string; + message: string; }; output?: unknown; }; diff --git a/src/content/docs/workflows/reference/limits.mdx b/src/content/docs/workflows/reference/limits.mdx index aa44dbfb0b8..8657f3b7caa 100644 --- a/src/content/docs/workflows/reference/limits.mdx +++ b/src/content/docs/workflows/reference/limits.mdx @@ -27,7 +27,7 @@ Workflows cannot be deployed to Workers for Platforms namespaces, as Workflows d | Maximum event [payload size](/workflows/build/events-and-parameters/) | 1MiB (2^20 bytes) | 1MiB (2^20 bytes) | | Maximum state that can be persisted per Workflow instance | 100MB | 1GB | | Maximum `step.sleep` duration | 365 days (1 year) | 365 days (1 year) | -| Maximum steps per Workflow [^5] | 1024 | 1024 | +| Maximum steps per Workflow [^5] | 10,000 (default) / configurable up to 25,000 | 10,000 (default) / configurable up to 25,000 | | Maximum Workflow executions | 100,000 per day [shared with Workers daily limit](/workers/platform/limits/#worker-limits) | Unlimited | | Concurrent Workflow instances (executions) per account [^7] | 100 | 10,000 | | Maximum Workflow instance creation rate [^8] | 100 per second [^6] | 100 per second [^6] | @@ -43,7 +43,7 @@ Workflows cannot be deployed to Workers for Platforms namespaces, as Workflows d [^4]: Match pattern: _```^[a-zA-Z0-9_][a-zA-Z0-9-_]\*$```\_ -[^5]: `step.sleep` do not count towards the max. steps limit +[^5]: `step.sleep` does not count towards the maximum steps limit [^6]: Workflows will return a HTTP 429 rate limited error if you exceed the rate of new Workflow instance creation. @@ -103,6 +103,10 @@ export class MyWorkflow extends WorkflowEntrypoint { 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 step limits + +Each Workflow instance supports 10,000 steps by default, but this can be increased up to 25,000 steps in your Wrangler configuration. Refer to [Workflow step limits](/workflows/build/workers-api/#workflowsteplimit) for more information. + ### 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.