Skip to Content
DocsWorkflows (vNext)Suspend & Resume

Suspend and Resume in Workflows

Complex workflows often need to pause execution while waiting for external input or resources.

Mastra’s suspend and resume features let you pause workflow execution at any step, persist the workflow snapshot to storage, and resume execution from the saved snapshot when ready. This entire process is automatically managed by Mastra. No config needed, or manual step required from the user.

Storing the workflow snapshot to storage (LibSQL by default) means that the workflow state is permanently preserved across sessions, deployments, and server restarts. This persistence is crucial for workflows that might remain suspended for minutes, hours, or even days while waiting for external input or resources.

When to Use Suspend/Resume

Common scenarios for suspending workflows include:

  • Waiting for human approval or input
  • Pausing until external API resources become available
  • Collecting additional data needed for later steps
  • Rate limiting or throttling expensive operations
  • Handling event-driven processes with external triggers

How to suspend a step

const humanInputStep = createStep({ id: "human-input", inputSchema: z.object({ suggestions: z.array(z.string()), vacationDescription: z.string(), }), resumeSchema: z.object({ selection: z.string(), }), suspendSchema: z.object({}), outputSchema: z.object({ selection: z.string().describe("The selection of the user"), vacationDescription: z.string(), }), execute: async ({ inputData, resumeData, suspend }) => { if (!resumeData?.selection) { await suspend({}); return { selection: "", vacationDescription: inputData?.vacationDescription, }; } return { selection: resumeData.selection, vacationDescription: inputData?.vacationDescription, }; }, });

How to resume step execution

Identifying suspended state

When running a workflow, its state can be one of the following:

  • running - The workflow is currently running
  • suspended - The workflow is suspended
  • success - The workflow has completed
  • failed - The workflow has failed

When the state is suspended, you can identify any and all steps that have been suspended by looking at the suspended property of the workflow.

const run = counterWorkflow.createRun(); const result = await run.start({ inputData: { startValue: 0 } }); if (result.status === "suspended") { const resumedResults = await run.resume({ step: result.suspended[0], resumeData: { newValue: 0 }, }); }

In this case, the logic resumes whatever is the first step reported as suspended.

The suspended property is of type string[][], where every array is a path to a step that has been suspended, the first element being the step id on the main workflow. If that step is a workflow itself, the second element is the step id on the nested workflow that was suspended, unless it is a workflow itself, in which case the third element is the step id on the nested workflow that was suspended, and so on.

Resume

// After getting user input const result = await workflowRun.resume({ step: userInputStep, // or 'myStepId' as a string resumeData: { userSelection: "User's choice", }, });

To resume a suspended nested workflow:

const result = await workflowRun.resume({ step: [nestedWorkflow, userInputStep], // or ['nestedWorkflowId', 'myStepId'] as a string array resumeData: { userSelection: "User's choice", }, });