Timeouts
Timeouts prevent workflows from hanging indefinitely when a step takes too long. You can set timeouts at the workflow level, the step level, or both.
Workflow-level timeout
Apply a default timeout to all steps in a workflow:
{ name: "ProcessOrder", timeoutMs: 30000, // 30 seconds per step steps: [ { type: "ValidateOrder", handler: validateOrder }, { type: "ChargePayment", handler: chargePayment }, { type: "FulfillOrder", handler: fulfillOrder }, ],}Every step inherits the 30-second timeout unless it specifies its own.
Step-level timeout
Override the workflow-level timeout for individual steps:
{ name: "ProcessOrder", timeoutMs: 30000, steps: [ { type: "ValidateOrder", handler: validateOrder }, { type: "ChargePayment", handler: chargePayment, timeoutMs: 60000, // override: 60 seconds for payment }, { type: "FulfillOrder", handler: fulfillOrder, timeoutMs: 10000 }, ],}Step-level timeoutMs takes precedence over the workflow-level value.
What happens on timeout
When a step exceeds its timeout:
- The step is treated as failed with a
TimeoutError. - If the step has an
onFailurebranch, execution routes to that step. - If no
onFailurebranch is configured, the workflow fails and triggers anyonFailureoronCompletechained workflows.
{ name: "ProcessDocument", steps: [ { type: "RunOCR", handler: runOCR, timeoutMs: 15000, onFailure: "HandleTimeout", }, { type: "HandleTimeout", handler: async (ctx) => { await alertOps("OCR timed out", ctx.payload); }, }, ],}Type definitions
type SynkroWorkflow = { name: string; steps: SynkroWorkflowStep[]; timeoutMs?: number; // default timeout for all steps onComplete?: string; onSuccess?: string; onFailure?: string;};
type SynkroWorkflowStep = { type: string; handler?: HandlerFunction; retry?: RetryConfig; onSuccess?: string; onFailure?: string; timeoutMs?: number; // overrides workflow-level timeout};