Wait
Pause a run for an interval, or until a date and time, and pick it up again.
A Wait node (wait) pauses a run and picks it up again later. The pause is durable: it is held by the
workflow engine, not by a process sitting on a timer, so a deploy or a restart in the middle of a
wait does not lose the run or shift when it resumes.
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
mode | interval | until | interval | After time interval or At specified time. |
amount | integer ≥ 1 | 1 | How long, in unit. Interval mode. |
unit | seconds | minutes | hours | days | hours | Interval mode. |
at | string | '' | The date and time to resume at, or a {{ }} expression that resolves to one. Until mode. |
timezone | IANA time zone | UTC | The zone at is read in. Ignored when at carries its own offset or Z. |
Two modes:
- After time interval — an amount and a unit (Seconds, Minutes, Hours, Days). A wait must be at
least 1 second and at most 365 days. A self-hosted deployment can lower that ceiling with the
WAIT_NODE_MAX_SECONDSenvironment variable. - At specified time — a date and time, or an expression that resolves to one (for example
{{ trigger.body.noticeDeadline }}), plus an IANA time zone.
In the second mode the time zone decides what the target means, and it is handled with the real
time-zone database, daylight saving included: 09:00 Europe/Sofia is 09:00 local on both sides of
a clock change. A target that already carries an offset (or a trailing Z) is used exactly as it
is and the zone is ignored. A target that has already passed is not an error — the run
continues immediately, and the node records target time already passed.
Every Wait node carries its own time zone, defaulting to UTC; there is no workspace-wide setting to inherit.
While a run is paused it shows as Waiting, with the instant it will resume at, in the Activity tab and through the public API. A waiting run does not count against your plan's limit on concurrent runs — nothing but the clock can release it. Stopping or cancelling a run while it is waiting ends it cleanly.
A Wait node cannot go inside a Loop body. The nodes in a loop body all run together as one step, which cannot hold a durable pause, so a Wait node there fails the loop with that reason rather than silently not pausing. Put the Wait before or after the loop instead.
A run's data is kept for 90 days from when the run finishes, so a wait longer than that window does not lose the data the run still needs.
Output
| Field | Type | Description |
|---|---|---|
mode | string | interval or until. |
resumeAt | string | When the run resumed, ISO 8601 UTC. |
timezone | string | The node's time zone. |
waitedMs | number | How long the run waited. |
alreadyPassed | boolean | The target time had already passed; the run did not wait. |
message | string | What the node did, in words. |
Limits and errors
- Between 1 second and 365 days (lower on a self-hosted deployment that sets
WAIT_NODE_MAX_SECONDS). The panel flags a value outside that range, and a run that reaches the node fails it, naming the limit. A target date further away than the limit fails the same way. - An
atvalue that is not a date and time fails the node. - Not inside a Loop body.
Example
Send a reminder three days after a form is submitted:
name: Follow-up
description: Reminds a customer three days after their request.
graph:
nodes:
- id: request
type: trigger_form
position: { x: 0, y: 0 }
data:
authMode: none
fields:
- { name: email, label: Your email, type: email, required: true }
- id: three-days
type: wait
position: { x: 280, y: 0 }
data:
mode: interval
amount: 3
unit: days
at: ''
timezone: Europe/Berlin
- id: remind
type: send_email
position: { x: 560, y: 0 }
data:
subject: How did we do?
body: Thanks for your request — reply to tell us how it went.
bodyFormat: text
attachments: []
edges:
- { id: request-to-wait, source: request, target: three-days }
- { id: wait-to-remind, source: three-days, target: remind }In a Package
- Travels:
mode,amount,unit,at,timezone - Converted: none
- Never carried: none