Workflows
Create stateful workflows that can orchestrate complex business processes, handle long-running operations, and guarantee the durable execution of your code in the face of a failure.

Catalyst provides a high-performant workflow runtime powered by Dapr Workflow, enabling you to author and operate reliable, long-running business processes defined in your application code.
Workflow as Code
Define workflows programmatically using any supported language SDK (Python, JavaScript, .NET, Java, Go), allowing you to express complex orchestration logic with the full power and flexibility of a programming language.
- Python
- JavaScript
- .NET
- Java
- Go
@wfr.workflow(name="request_escalation")
def request_escalation_workflow(ctx: DaprWorkflowContext, order_str: str):
order = json.loads(order_str) if isinstance(order_str, str) else order_str
amount = order.get("amount", 0)
# Auto-approve orders under $1000
if amount < 1000:
yield ctx.call_activity(auto_approve_activity, input=order)
return
# Orders $1000+ require human approval (7 days max)
approval_event = ctx.wait_for_external_event("human_approval")
timeout = ctx.create_timer(timedelta(days=7))
winner = yield when_any([approval_event, timeout])
# Handle approval event or timeout
if winner == timeout:
yield ctx.call_activity(handle_timeout_activity, input=order)
return
approval_result = approval_event.get_result()
yield ctx.call_activity(process_approval_activity, input=approval_result)
const requestEscalationWorkflow: TWorkflow = async function* (
ctx: WorkflowContext,
order: OrderRequest
): any {
// Auto-approve orders under $1000
if (order.amount < 1000) {
yield ctx.callActivity(autoApproveActivity, order);
return;
}
// Orders $1000+ require human approval (7 days max)
const approvalEvent = ctx.waitForExternalEvent("human_approval");
const timeout = ctx.createTimer(7 * 24 * 60 * 60);
const winner = yield ctx.whenAny([approvalEvent, timeout]);
// Handle approval event or timeout
if (winner == timeout) {
yield ctx.callActivity(handleTimeoutActivity, order);
return;
}
const approvalResult = approvalEvent.getResult();
yield ctx.callActivity(processApprovalActivity, approvalResult);
};
// Workflow Definition
public class RequestEscalationWorkflow : Workflow<OrderRequest, object>
{
public override async Task<object> RunAsync(WorkflowContext context, OrderRequest order)
{
// Auto-approve orders under $1000
if (order.Amount < 1000)
{
await context.CallActivityAsync(nameof(AutoApproveActivity), order);
return null;
}
// Orders $1000+ require human approval (7 days max)
try
{
var approval = await context.WaitForExternalEventAsync<ApprovalResult>(
eventName: "human_approval",
timeout: TimeSpan.FromDays(7));
// Handle approval event
await context.CallActivityAsync(nameof(ProcessApprovalActivity), approval);
return null;
}
catch (TaskCanceledException)
{
// Handle timeout - no approval received within 7 days
await context.CallActivityAsync(nameof(HandleTimeoutActivity), order);
return null;
}
}
}
// Workflow Definition
@Component
public static class RequestEscalationWorkflow implements Workflow {
@Override
public WorkflowStub create() {
return ctx -> {
OrderRequest order = ctx.getInput(OrderRequest.class);
// Auto-approve orders under $1000
if (order.amount < 1000) {
ctx.callActivity("AutoApproveActivity", order).await();
ctx.complete("approved");
return;
}
// Orders $1000+ require human approval (7 days max)
try {
ApprovalResult approval = ctx.waitForExternalEvent("human_approval", Duration.ofDays(7), ApprovalResult.class).await();
ctx.callActivity("ProcessApprovalActivity", approval).await();
} catch (TaskCanceledException e) {
// Handle timeout
ctx.callActivity("HandleTimeoutActivity", order).await();
}
ctx.complete("order completed");
};
}
}
// Workflow Definition
func RequestEscalationWorkflow(ctx *workflow.WorkflowContext) (any, error) {
var order OrderRequest
if err := ctx.GetInput(&order); err != nil {
return nil, err
}
// Auto-approve orders under $1000
if order.Amount < 1000 {
return nil, ctx.CallActivity(AutoApproveActivity, workflow.WithActivityInput(order)).Await(nil)
}
// Orders $1000+ require human approval (7 days max)
var approval ApprovalResult
err := ctx.WaitForExternalEvent("human_approval", time.Hour*24*7).Await(&approval)
// Handle approval event or timeout
if err == nil {
return nil, ctx.CallActivity(ProcessApprovalActivity, workflow.WithActivityInput(approval)).Await(nil)
}
return nil, ctx.CallActivity(HandleTimeoutActivity, workflow.WithActivityInput(order)).Await(nil)
}
Key features:
- Durability - Every workflow step is persisted in a backing store (SQL, NoSQL, or cloud service), which allows workflows to survive process restarts and continue from their last recorded state.
- Resiliency - Workflows apply durable retry policies that track retry state, wait with durable timers, and continue after restarts. Built-in retries, timeouts, and circuit breakers. These policies operate independently of Dapr resiliency.
- Child workflows - Compose complex processes by breking them down into sub processes
- Multi-application workflows - Orchestrate business processes that span across different application instances. This enables you to reuse existing workflows and their activities in new workflows for example.
- Timers and reminders - Schedule delays or future events.
- External events - Wait for human approvals or external triggers.
Observability and Auditing
Catalyst provides deep workflow observability through a unified dashboard that tracks all executions, workflow states, and success rates. You can view summaries by workflow type, drill down into individual runs, and visualize execution paths to understand how each activity progressed or failed.

Key features:
- Workflow dashboard - Monitor workflow execution states (Running, Completed, Failed) and aggregate success rates across workflows for quick health insights.
- Execution visualization - View real-time diagrams of workflow paths, including branching, parallel activities, and dependencies.
- Execution history - View full workflow timelines, duration, and outcomes.
- Input and output inspection - Examine data at each stage for debugging and monitoring.
- API logs - Inspect real-time Dapr API calls including Workflow, State, Pub/Sub, and Invocation APIs directly for end-to-end visibility.
Workflow Patterns
Catalyst supports common stateful coordination patterns in microservice architectures.
Task Chaining

Multiple steps in a workflow run in succession, with the output of one step passed as input to the next step. Ideal for sequential data processing operations like filtering, transforming, and reducing.
Read more →Fan-out/Fan-in

Execute multiple tasks simultaneously across potentially multiple workers, wait for them to finish, and perform aggregation on the results. Perfect for parallel processing with dynamic task counts.
Read more →Async HTTP APIs

Implement asynchronous request-reply patterns where clients receive immediate acknowledgment and can poll for completion status. Built-in support for long-running operations without custom state management.
Read more →Monitor

Recurring process that checks system status, takes action based on that status, sleeps for a period, and repeats. Supports dynamic sleep intervals and graceful termination.
Read more →External System Interaction

Pause and wait for external systems or human input to perform actions. Supports timeouts, event-driven resumption, and compensation logic for approval workflows and payment processing.
Read more →Compensation

Roll back or undo operations that have already been executed when a workflow fails partway through. Essential for maintaining consistency in distributed transactions across microservices.
Read more →