Skip to Content
DocsWorkflowsSuspend & Resume

Suspend & Resume

Workflows can be paused at any step, with their current state persisted as a snapshot in storage. Execution can then be resumed from this saved snapshot when ready. Persisting the snapshot ensures the workflow state is maintained across sessions, deployments, and server restarts, essential for workflows that may remain suspended while awaiting external input or resources.

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

Workflow Status

When running a workflow, its status 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

Suspend

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

src/mastra/workflows/test-workflow.ts
const step1 = createStep({ id: "step-1", description: "Test suspend", inputSchema: z.object({ input: z.array(z.string()) }), resumeSchema: z.object({ city: z.string() }), outputSchema: z.object({ output: z.string() }), execute: async ({ resumeData, suspend }) => { const { city } = resumeData ?? {}; if (!city) { await suspend({}); return { outcome: "" }; } return { output: "" }; } }); export const testWorkflow = createWorkflow({}) .then(step1) .commit();

See Define Suspendable workflow for more information.

Resume

A workflow can be resumed by calling resume and providing the required resumeData.

src/test-workflow.ts
import { mastra } from "./mastra"; const run = mastra.getWorkflow("testWorkflow").createRun(); const result = await run.start({ inputData: { suggestions: ["London", "Paris", "New York"] } }); console.log(JSON.stringify(result, null, 2)); if (result.status === "suspended") { const resumedResult = await run.resume({ step: 'step-1', resumeData: { city: "New York" } }); console.log(JSON.stringify(resumedResult, null, 2)); }

To execute this run from your terminal:

npx tsx src/test-workflow.ts

Nested Workflow

To resume a suspended nested workflow pass the workflow instance to the step parameter of the resume function.

src/test-workflow.ts
const dowhileWorkflow = createWorkflow({ id: 'dowhile-workflow', inputSchema: z.object({ value: z.number() }), outputSchema: z.object({ value: z.number() }), }) .dountil( createWorkflow({ id: 'simple-resume-workflow', inputSchema: z.object({ value: z.number() }), outputSchema: z.object({ value: z.number() }), steps: [incrementStep, resumeStep], }) .then(incrementStep) .then(resumeStep) .commit(), async ({ inputData }) => inputData.value >= 10, ) .then( createStep({ id: 'final', inputSchema: z.object({ value: z.number() }), outputSchema: z.object({ value: z.number() }), execute: async ({ inputData }) => ({ value: inputData.value }), }), ) .commit(); const run = dowhileWorkflow.createRun(); const result = await run.start({ inputData: { value: 0 } }); if (result.status === "suspended") { const resumedResult = await run.resume({ resumeData: { value: 2 }, step: ['simple-resume-workflow', 'resume'], }); console.log(JSON.stringify(resumedResult, null, 2)); }

RuntimeContext

When using suspend/resume with RuntimeContext, you can create the instance yourself, and pass it to the start and resume functions. RuntimeContext is not automatically shared on a workflow run.

src/test-workflow.ts
import { RuntimeContext } from "@mastra/core/di"; import { mastra } from "./mastra"; const runtimeContext = new RuntimeContext(); const run = mastra.getWorkflow("testWorkflow").createRun(); const result = await run.start({ inputData: { suggestions: ["London", "Paris", "New York"] }, runtimeContext }); if (result.status === "suspended") { const resumedResult = await run.resume({ step: 'step-1', resumeData: { city: "New York" }, runtimeContext }); }