Workflows
Build durable, multi-step workflows with automatic retries and state persistence.
Workflows
Ploy Workflows let you define long-running, multi-step processes that survive failures. Each step is durably persisted and automatically retried on errors.
Configuration
Add a workflow binding in your ploy.yaml:
kind: worker
build: pnpm build
out: dist
workflow:
ORDER_FLOW: order_processingThe key (ORDER_FLOW) is the binding name. The value (order_processing) must match the workflow function name in your code.
Run ploy types to generate TypeScript types:
import type { WorkflowBinding } from "@meetploy/types";
export interface Env {
ORDER_FLOW: WorkflowBinding;
}Basic Example
import type { Env } from "./env.js";
import type { Ploy, WorkflowContext } from "@meetploy/types";
export default {
async fetch(request, env) {
// Trigger a workflow execution
const { executionId } = await env.ORDER_FLOW.trigger({
orderId: "123",
amount: 99.99,
});
return Response.json({ executionId });
},
workflows: {
async order_processing({
input,
step,
}: WorkflowContext<Env, { orderId: string; amount: number }>) {
// Step 1: Validate
const order = await step.run("validate", async () => {
return { valid: true, orderId: input.orderId };
});
// Step 2: Charge payment
const payment = await step.run("charge", async () => {
return { paymentId: `pay_${Date.now()}` };
});
// Step 3: Fulfill
const fulfillment = await step.run("fulfill", async () => {
return { trackingNumber: `TRACK_${Date.now()}` };
});
return { orderId: order.orderId, paymentId: payment.paymentId };
},
},
} satisfies Ploy<Env>;Workflow Binding API
Trigger
Start a new workflow execution:
const { executionId } = await env.ORDER_FLOW.trigger({ orderId: "123" });Get Status
Check execution status:
const execution = await env.ORDER_FLOW.getExecution(executionId);
// { status: "running" | "completed" | "failed", result?: any }Cancel
Cancel a running execution:
await env.ORDER_FLOW.cancel(executionId);Step API
step.run
Execute a named step. Results are persisted, so re-runs skip completed steps:
const result = await step.run("step-name", async () => {
return { data: "value" };
});step.sleep
Pause execution for a duration (in milliseconds):
await step.sleep(5000); // Wait 5 secondsSteps that throw are automatically retried. Use unique step names to ensure idempotency.
Next Steps
How is this guide?
Last updated on