3.7.11. Store Workflow Executions

In this chapter, you'll learn how to store workflow executions in the database and access them later.

Workflow Execution Retention#

Medusa doesn't store your workflow's execution details by default. However, you can configure a workflow to keep its execution details stored in the database.

This is useful for auditing and debugging purposes. When you store a workflow's execution, you can view details around its steps, their states and their output. You can also check whether the workflow or any of its steps failed.

Tip: You can view stored workflow executions from the Medusa Admin dashboard by going to Settings -> Workflows.

How to Store Workflow's Executions?#

createWorkflow from the Workflows SDK can accept an object as a first parameter to set the workflow's configuration. To enable storing a workflow's executions:

  • Enable the store option. If your workflow is a Long-Running Workflow, this option is enabled by default.
  • Set the retentionTime option to the number of seconds that the workflow execution should be stored in the database.

For example:

Code
1import { createStep, createWorkflow } from "@medusajs/framework/workflows-sdk"2
3const step1 = createStep(4  {5    name: "step-1",6  },7  async () => {8    console.log("Hello from step 1")9  }10)11
12export const helloWorkflow = createWorkflow(13  {14    name: "hello-workflow",15    retentionTime: 99999,16    store: true,17  },18  () => {19    step1()20  }21)

Whenever you execute the helloWorkflow now, its execution details will be stored in the database.


Retrieve Workflow Executions#

Tip: You can view stored workflow executions from the Medusa Admin dashboard by going to Settings -> Workflows.

When you execute a workflow, the returned object has a transaction property containing the workflow execution's transaction details:

Code
const { transaction } = await helloWorkflow(container).run()

To retrieve a workflow's execution details from the database, resolve the Workflow Engine Module from the container and use its listWorkflowExecutions method.

For example, you can create a GET API Route at src/workflows/[id]/route.ts that retrieves a workflow execution for the specified transaction ID:

src/workflows/[id]/route.ts
1import { MedusaRequest, MedusaResponse } from "@medusajs/framework"2import { Modules } from "@medusajs/framework/utils"3
4export async function GET(5  req: MedusaRequest,6  res: MedusaResponse7) {8  const { transaction_id } = req.params9  10  const workflowEngineService = req.scope.resolve(11    Modules.WORKFLOW_ENGINE12  )13
14  const [workflowExecution] = await workflowEngineService.listWorkflowExecutions({15    transaction_id: transaction_id,16  })17
18  res.json({19    workflowExecution,20  })21}

In the above example, you resolve the Workflow Engine Module from the container and use its listWorkflowExecutions method, passing the transaction_id as a filter to retrieve its workflow execution details.

A workflow execution object will be similar to the following:

Code
1{2  "workflow_id": "hello-workflow",3  "transaction_id": "01JJC2T6AVJCQ3N4BRD1EB88SP",4  "id": "wf_exec_01JJC2T6B3P76JD35F12QTTA78",5  "execution": {6    "state": "done",7    "steps": {},8    "modelId": "hello-workflow",9    "options": {},10    "metadata": {},11    "startedAt": 1737719880027,12    "definition": {},13    "timedOutAt": null,14    "hasAsyncSteps": false,15    "transactionId": "01JJC2T6AVJCQ3N4BRD1EB88SP",16    "hasFailedSteps": false,17    "hasSkippedSteps": false,18    "hasWaitingSteps": false,19    "hasRevertedSteps": false,20    "hasSkippedOnFailureSteps": false21  },22  "context": {23    "data": {},24    "errors": []25  },26  "state": "done",27  "created_at": "2025-01-24T09:58:00.036Z",28  "updated_at": "2025-01-24T09:58:00.046Z",29  "deleted_at": null30}

Example: Check if Stored Workflow Execution Failed#

To check if a stored workflow execution failed, you can check its state property:

Code
1if (workflowExecution.state === "failed") {2  return res.status(500).json({3    error: "Workflow failed",4  })5}

Other state values include done, invoking, and compensating.

Was this chapter helpful?
Ask Anything
FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break