YeetCode
Convex App

Workflows

Multi-step operations and workflow cleanup in Convex.

YeetCode includes support for Convex Workflows (@convex-dev/workflow) — a system for orchestrating multi-step operations that need to survive server restarts and handle failures gracefully.

Why Workflows

Regular Convex actions can time out. If you need to coordinate multiple steps (e.g., charge a payment → create subscription → send email), a workflow ensures each step completes even if the server restarts between them.

Workflow Cleanup

Completed workflows consume database space. YeetCode includes a cleanup utility in apps/convex/utils.ts that waits for a workflow to finish and then removes its state from the database:

import { cleanUpWorkflow } from "./utils";

// In an action:
await cleanUpWorkflow(ctx, workflow, workflowId);

How It Works

export async function cleanUpWorkflow(
  ctx: ActionCtx,
  workflow: WorkflowManager,
  workflowId: WorkflowId
): Promise<void> {
  // Poll until the workflow completes
  while (true) {
    const status = await workflow.status(ctx, workflowId);
    if (status.type === "inProgress") {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      continue;
    }
    break;
  }
  // Clean up workflow state from the database
  await workflow.cleanup(ctx, workflowId);
}

The function polls every second until the workflow is no longer in progress, then cleans up its database records. This is done in a finally block to ensure cleanup happens even if an error occurs.

Why Manual Cleanup

After working with the Convex team, manual cleanup was chosen over automatic cleanup for better predictability. Without cleanup:

  • Database backups grow large
  • Database bandwidth charges increase
  • Storage costs accumulate over time

Manual cleanup gives you control over when workflow state is removed.

On this page