diff --git a/src/content/docs/workflows/reference/limits.mdx b/src/content/docs/workflows/reference/limits.mdx
index 9ea7e5d6673b11..0d201c075aded9 100644
--- a/src/content/docs/workflows/reference/limits.mdx
+++ b/src/content/docs/workflows/reference/limits.mdx
@@ -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] |
@@ -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.
+
+### `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. This 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, on a best-effort basis. This state transition - `running` to `waiting` - may not occur if the wait duration 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 {
+ async run(event: WorkflowEvent, 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();
+ });
+
+ 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.