Cloudflare Workflows reaches GA

Cloudflare has announced that Workflows, its serverless durable execution engine for building long-running, multi-step applications on Workers, is now generally available. The GA release marks the service as production-ready, though development continues with plans for more concurrent instances, new APIs, and deeper integration with AI agent tooling.

The core idea behind Workflows is a step-based architecture where each step in an application is independently retriable and state is automatically persisted between steps. If a step fails due to a transient error or network issue, Workflows can retry only that step rather than restarting the entire application. Steps can execute code via step.do, sleep via step.sleep or step.sleepUntil, or wait for external input via step.waitForEvent.

This model suits applications that coordinate multiple systems, process data sequentially, or handle tasks spanning minutes, hours, or days. A typical e-commerce workflow, for instance, may check inventory, charge a payment, send a confirmation email, and update a database as separate steps. If the payment service is temporarily unavailable, only that step is retried—the inventory check is not duplicated and the process does not restart from the beginning.

Waiting on the real world

Workflows are ordinary code, which means steps can be defined dynamically, branch conditionally, and make calls to any external system. But some workflows need to pause until something happens in the real world: a human approval, an incoming webhook from Stripe or GitHub, or a state change like a file upload to R2 that triggers an Event Notification and passes a reference to the Workflow for processing.

The new waitForEvent API provides exactly this capability. Events can be sent to a specific Workflow instance from any external service via an HTTP request, or from within a Worker via the Workers API. The API supports waiting for multiple events using the type parameter, and Promise.race can be used to continue when the first of several events arrives.

Consider a code review agent that watches a GitHub repository. Without event waiting, the workflow cannot easily request human approval before writing suggestions or submitting a pull request. The alternative is polling: calling step.sleep for arbitrary intervals, checking a storage service for an updated value, and repeating—resulting in more code and more room for error. With waitForEvent, the workflow can pause until explicit human approval is received before making a mutating change.

An AI agent could even act on behalf of a human in this loop. Because waitForEvent is just another step, it can be called conditionally, multiple times, or inside a loop. Workflows are Workers, so developers get the full power of a programming language rather than being constrained by a domain-specific language or configuration format.

Pricing and billing

Pricing remains largely unchanged from the beta period, with CPU-based and request-based billing retained and one addition: storage pricing for state persisted by Workflows.

Storage billing will not be actively charged until September 15, 2025. Users above the included 1 GB limit will be notified ahead of time. By default, Workflows will expire stored state after three days on the Free plan and thirty days on the Paid plan.

CPU time refers only to time spent actively consuming compute resources. It does not include time waiting on API calls, reasoning LLMs, or I/O such as database writes. This distinction matters in practice: most applications use only single-digit milliseconds of CPU time while spending multiple seconds of wall time waiting on APIs that take 100–250 ms to respond. Workflow engines especially spend much of their time waiting—on object storage reads from R2, third-party APIs, LLMs like o3-mini or Claude 3.7, or queries to D1, Postgres, and MySQL. With Workflows, as with Workers, you do not pay for time spent waiting.

Getting started

Developers ready to build with Workflows can start by visiting the documentation to learn about the API and best practices, reviewing the code in the starter project on GitHub, and deploying the starter directly to a Cloudflare account using the provided deploy link.