# Suspend & Resume Workflows can be paused at any step to collect additional data, wait for API callbacks, throttle costly operations, or request [human-in-the-loop](https://mastra.ai/docs/workflows/human-in-the-loop) input. When a workflow is suspended, its current execution state is saved as a snapshot. You can later resume the workflow from a [specific step ID](https://mastra.ai/docs/workflows/snapshots), restoring the exact state captured in that snapshot. [Snapshots](https://mastra.ai/docs/workflows/snapshots) are stored in your configured storage provider and across deployments and application restarts. ## Pausing a workflow with `suspend()` Use `suspend()` to pause workflow execution at a specific step. You can define a suspend condition in the step’s `execute` block using values from `resumeData`. - If the condition isn’t met, the workflow pauses and returns `suspend()`. - If the condition is met, the workflow continues with the remaining logic in the step. ![Pausing a workflow with suspend()](/assets/images/workflows-suspend-4540783670f918109ac35beaf4db914b.jpg) ```typescript const step1 = createStep({ id: "step-1", inputSchema: z.object({ userEmail: z.string() }), outputSchema: z.object({ output: z.string() }), resumeSchema: z.object({ approved: z.boolean() }), execute: async ({ inputData, resumeData, suspend }) => { const { userEmail } = inputData; const { approved } = resumeData ?? {}; if (!approved) { return await suspend({}); } return { output: `Email sent to ${userEmail}` }; } }); export const testWorkflow = createWorkflow({ id: "test-workflow", inputSchema: z.object({ userEmail: z.string() }), outputSchema: z.object({ output: z.string() }) }) .then(step1) .commit(); ``` ## Restarting a workflow with `resume()` Use `resume()` to restart a suspended workflow from the step where it paused. Pass `resumeData` matching the step's `resumeSchema` to satisfy the suspend condition and continue execution. ![Restarting a workflow with resume()](/assets/images/workflows-resume-1e54b4d0c753ff79571f6d6b05109a60.jpg) ```typescript import { step1 } from "./workflows/test-workflow"; const workflow = mastra.getWorkflow("testWorkflow"); const run = await workflow.createRun(); await run.start({ inputData: { userEmail: "alex@example.com" } }); const handleResume = async () => { const result = await run.resume({ step: step1, resumeData: { approved: true } }); }; ``` Passing the `step` object provides full type-safety for `resumeData`. Alternatively, you can pass a step ID for more flexibility when the ID comes from user input or a database. ```typescript const result = await run.resume({ step: "step-1", resumeData: { approved: true } }); ``` If only one step is suspended, you can omit the step argument entirely and Mastra will resume the last suspended step in the workflow. When resuming with only a `runId`, create a run instance first using `createRun()`. ```typescript const workflow = mastra.getWorkflow("testWorkflow"); const run = await workflow.createRun({ runId: "123" }); const stream = run.resume({ resumeData: { approved: true } }); ``` You can call `resume()` from anywhere in your application, including HTTP endpoints, event handlers, in response to [human input](https://mastra.ai/docs/workflows/human-in-the-loop), or timers. ```typescript const midnight = new Date(); midnight.setUTCHours(24, 0, 0, 0); setTimeout(async () => { await run.resume({ step: "step-1", resumeData: { approved: true } }); }, midnight.getTime() - Date.now()); ``` ## Accessing suspend data with `suspendData` When a step is suspended, you may want to access the data that was provided to `suspend()` when the step is later resumed. Use the `suspendData` parameter in your step's execute function to access this data. ```typescript const approvalStep = createStep({ id: "user-approval", inputSchema: z.object({ requestId: z.string() }), resumeSchema: z.object({ approved: z.boolean() }), suspendSchema: z.object({ reason: z.string(), requestDetails: z.string() }), outputSchema: z.object({ result: z.string() }), execute: async ({ inputData, resumeData, suspend, suspendData }) => { const { requestId } = inputData; const { approved } = resumeData ?? {}; // On first execution, suspend with context if (!approved) { return await suspend({ reason: "User approval required", requestDetails: `Request ${requestId} pending review` }); } // On resume, access the original suspend data const suspendReason = suspendData?.reason || "Unknown"; const details = suspendData?.requestDetails || "No details"; return { result: `${details} - ${suspendReason} - Decision: ${approved ? 'Approved' : 'Rejected'}` }; } }); ``` The `suspendData` parameter is automatically populated when a step is resumed and contains the exact data that was passed to the `suspend()` function during the original suspension. This allows you to maintain context about why the workflow was suspended and use that information during the resume process. ## Identifying suspended executions When a workflow is suspended, it restarts from the step where it paused. You can check the workflow's `status` to confirm it's suspended, and use `suspended` to identify the paused step or [nested workflow](https://mastra.ai/docs/workflows/overview). ```typescript const workflow = mastra.getWorkflow("testWorkflow"); const run = await workflow.createRun(); const result = await run.start({ inputData: { userEmail: "alex@example.com" } }); if (result.status === "suspended") { console.log(result.suspended[0]); await run.resume({ step: result.suspended[0], resumeData: { approved: true } }); } ``` **Example output** The `suspended` array contains the IDs of any suspended workflows and steps from the run. These can be passed to the `step` parameter when calling `resume()` to target and resume the suspended execution path. ```typescript [ 'nested-workflow', 'step-1' ] ``` ## Sleep Sleep methods can be used to pause execution at the workflow level, which sets the status to `waiting`. By comparison, `suspend()` pauses execution within a specific step and sets the status to `suspended`. **Available methods:** - [`.sleep()`](https://mastra.ai/reference/workflows/workflow-methods/sleep): Pause for a specified number of milliseconds - [`.sleepUntil()`](https://mastra.ai/reference/workflows/workflow-methods/sleepUntil): Pause until a specific date ## Related - [Control Flow](https://mastra.ai/docs/workflows/control-flow) - [Human-in-the-loop](https://mastra.ai/docs/workflows/human-in-the-loop) - [Snapshots](https://mastra.ai/docs/workflows/snapshots) - [Time Travel](https://mastra.ai/docs/workflows/time-travel)