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.