Every limit is set per deployment, so the same flow can be throttled in one place and unrestricted in another.
| Setting | Default | What it bounds |
|---|---|---|
| Concurrency | 1 | How many of this deployment's executions run at the same time |
| Rate limit | unlimited | New executions per minute, across all of its triggers |
| Timeout | 300 s | Wall-clock seconds before a run is force-failed |
| Memory | 100 MB | The worker's memory ceiling |
| Max retries | 0 | Retry attempts per failing step |
The default is 1: this deployment processes one delivery at a time and the rest queue. That is
usually what you want for anything writing to an outside system, because it makes ordering and
duplicate-handling straightforward.
Raise it when the work is independent and the downstream system can take it. Queued deliveries are not lost — they wait.
A ceiling on new executions per minute across every trigger of this deployment. It is the control for an outside API with its own quota, applied before anything starts rather than by failing mid-run.
Wall-clock seconds for one execution. Exceeding it force-fails the run as a whole — it is not a
step failure, so it is not retried by maxRetries.
Time spent paused, delayed or waiting on a rerun does not consume it: those re-queue
the execution instead of holding a worker, which is exactly why they are the right way to wait.
CPU-time and I/O ceilings are derived from the timeout rather than set separately. One of them behaves differently and is worth knowing: exceeding the I/O allowance does not kill the run. The transfer in flight and every later I/O call throw a catchable error, and your code carries on.
The worker's isolate cap in MB. Streaming exists partly for this: payloadStream() over
payloadBytes(), and streamed emits, keep a large body out of the worker entirely.
Limits belong to the deployment, not to the flow, so: