shiichan

Saga Rollbacks Land in Workflows!

Hey there, it's Shii-chan! Today I've got a neat little update to Cloudflare's Workflows. Cleaning up after a failure just got a lot easier to write.

Cloudflare Changelog developers.cloudflare.com

What was announced?

Workflows added saga-style rollback support. This one was announced on Cloudflare's Changelog. You can attach compensating logic to each step.do() call, and when an instance fails, those rollback handlers run in reverse step-start order.

The story so far

Up to now, the cleanup for a multi-step process that failed partway through usually lived in one big top-level catch block. For operations that touch external systems, like inventory reservations, payment authorization, ticket creation, or infrastructure provisioning, that catch block could get messy fast, since you had to remember which step to undo and how.

What changes

Now you can put the undo logic right next to the step it reverses. A "cancel the payment" action next to the step that authorized it, a "delete the resource" action next to the step that created it, and so on. Your cleanup code stops scattering around, which is kinder to whoever reads it later.

Dive Deep

The usage is straightforward: you pass a rollback handler in the options for step.do(). And the rollback path gets its own retry and timeout configuration.

await step.do(
  "provision resource",
  async () => {
    const resource = await provisionResource();
    return { resourceId: resource.id };
  },
  {
    rollback: async ({ output }) => {
      const { resourceId } = output;
      await deleteResource(resourceId);
    },
    rollbackConfig: {
      retries: { limit: 3, delay: "15 seconds", backoff: "linear" },
      timeout: "2 minutes",
    },
  },
);

With rollbackConfig you set the retry limit, delay, backoff, and timeout separately from the normal step. Workflows also surfaces rollback outcomes in the instance status response and emits rollback lifecycle events in analytics, so during production debugging you can tell a forward-execution failure apart from a rollback failure. The full set of settings is documented in rollback options.

Wrap-up

  • Workflows added saga-style rollback support (announced on Cloudflare's Changelog)
  • Attach a rollback handler to step.do(), and on failure the undo logic runs in reverse order
  • Rollbacks get their own rollbackConfig for retries and timeout
  • Outcomes show up in the instance status, and lifecycle events let you separate forward failures from rollback failures

This is a great fit if you build multi-step flows in Workflows where a mid-way failure really hurts, like payments or infrastructure provisioning!