workflows & triggers Background work, on the same canvas.
A workflow is built exactly like a route — same blocks, same integrations, same custom blocks — but nobody waits for it. Schedules, queues and other routes start it; workers run it.
Read the docsroute or workflow?
Same blocks, different contract.
Rule of thumb: if someone is waiting for the answer, it's a route. If the work can happen later — sending email, syncing data, processing an upload — hand it to a workflow with the Trigger Workflow block and answer right away.
| Route | Workflow | |
|---|---|---|
| Starts when | someone calls its URL | a trigger fires, a schedule ticks, or you run it |
| Who waits | the caller, connection open | nobody |
| Gives back | an HTTP response | nothing — it finishes |
| Time limit | 30 seconds | 5 minutes, up to an hour |
| If it fails | the caller sees an error | it's retried automatically |
batching
Handle events by the hundred, not one by one.
Set a batch size and a trigger collects events into one run. Writing 500 rows once is far cheaper than writing one row 500 times. Concurrency lets several batches run at once — at the cost of ordering.
failures
Nobody's waiting, so it tries again.
A failed workflow run is retried with a pause in between. Queue triggers go further: a dead-letter destination catches messages that keep failing, so one bad event can't block the rest.
schedules
On the clock.
A schedule is a trigger that fires on time instead of on an event. Intervals, cron, daily or a single moment — previewed before you save.
placement
Noisy triggers get their own workers.
Triggers belong to groups. Start workers with a group id and they run only that group's triggers, so a firehose of events can't slow your APIs. Workers can serve routes, workflows, or both.
- Default group every trigger lands here unless you choose otherwise
- WORKER_GROUP_ID start a worker that only runs one group's triggers
- Worker types route, workflow, or both — on Community, one worker does both