Cloudflare Workflows Billing: Steps and State Storage
Cloudflare Workflows has reached the billing boundary announced for August 10, 2026. Cloudflare’s current Workflows pricing documents steps and persisted state for Workers Paid alongside Workers requests and CPU time. The useful response is an audit of execution paths and retained state, not a blanket rewrite of every Workflow.
The billing changelog gives August 10 as the start date. That date tells you which usage window to inspect; it does not replace the account’s dashboard or invoice. Keep the exact billing period and plan beside your measurements so an estimate is not mistaken for a charge.
What Cloudflare Workflows now puts on the bill
Cloudflare documents four billing dimensions for Workflows:
| Dimension | What it measures | What to inspect |
|---|---|---|
| Requests | New Workflow invocations | Every API, Worker, CLI, or scheduled entry point |
| CPU time | Active compute time | CPU-heavy callbacks and transformations |
| Steps | Executed Workflow operations | step.do(), sleeps, waits, and how branches or loops repeat them |
| Storage | Persisted Workflow state | Returned step data, instance count, size, and retention |
The published allowances are different on each plan:
| Usage | Workers Free | Workers Paid |
|---|---|---|
| Steps | 3,000 per day | 500,000 per month, then $0.80 per additional 100,000 |
| Storage | 1 GB-month included | 1 GB-month included, then $0.20 per GB-month |
Workflows remain available on both plans. Cloudflare says Workers Free users are not charged for steps or storage beyond the included amounts, while Paid users still need to account for requests and CPU time separately.
Count execution paths, not source lines
The number of step.do() calls in a file is only a starting inventory. A conditional branch may run one path or another; a loop can execute a step many times; and a long-lived Workflow can visit sleep or event-wait operations between active callbacks.
Cloudflare’s changelog defines a step as each unit of work executed by a Workflow, including sleep and wait-for-event operations. Its Workers API documentation separately notes that step.sleep() and step.sleepUntil() do not count toward the maximum steps-per-Workflow limit. Those are different questions: a sleep can be excluded from the execution limit while still belonging in a billing audit.
Start with a repository scan to build an inventory:
rg -n \ 'step\\.(do|sleep|sleepUntil|waitForEvent)' \ src test tests \ --glob '!node_modules/**' \ --glob '!dist/**'Then classify each match:
- Fixed path: one invocation runs a known sequence of steps.
- Branching path: a condition skips or adds work depending on the payload or an external response.
- Repeated path: a loop, batch, or retry policy can make the same operation run multiple times.
- Waiting path: a Workflow sleeps or waits for an event before continuing.
This classification gives you a more useful estimate than multiplying the number of step.do() strings by the number of instances. Use the dashboard to compare the estimate with observed runs, and keep the estimate labelled as a model rather than a bill.
Check steps and failures in the dashboard
Cloudflare exposes Workflows execution metrics in the dashboard and through the workflowsAdaptiveGroups GraphQL dataset. The documented dimensions include the Workflow name, instance ID, step name, event type, and stepCount; the raw workflowsAdaptive data also exposes eventType, stepCount, and timing fields for an instance.
For a first pass, open the Workflows page in the Cloudflare dashboard and review a consistent time window for each Workflow. Record:
- Total invocations and the busiest hours.
- The steps reached by successful and failed paths.
- Workflows with frequent
SLEEP_*,STEP_FAILURE, orWORKFLOW_FAILUREevents. - Whether a high step count comes from normal branching, a loop, or a repeated failure path.
The last item is the one worth investigating. Removing a useful step can make a Workflow harder to retry or observe. A repeated failing step can be both a reliability problem and an avoidable source of execution activity, so fix the failure boundary before shortening the workflow for its own sake.
If you need to reproduce Worker-bound entry points and failure paths locally, pair the dashboard review with a Cloudflare Workers test harness.
Treat retained state as a separate budget
Step volume and state storage grow for different reasons. A Workflow may have a modest number of steps but retain a large response for every instance. Cloudflare calculates storage in GB-months using the average peak storage per day across a 30-day billing period. Running, errored, sleeping, and completed instances all contribute to the stored state.
The default retention is three days on Workers Free and 30 days on Workers Paid. You can set shorter success and error retention when a Workflow does not need to keep its full state for that long:
const instance = await env.MY_WORKFLOW.create({ params: { orderId }, retention: { successRetention: "1 day", errorRetention: "7 days", },});Do not use one short retention value for every workflow without checking the operational purpose of the data. A useful split is:
- Keep error state long enough to reproduce and triage failures.
- Keep successful state only as long as the product or audit process needs it.
- Return identifiers or compact summaries when the full payload already lives in a database or object store.
- Move large, long-lived artifacts to external storage such as R2 and keep a reference in the Workflow state.
Cloudflare’s Workers API documentation also makes the retention distinction explicit: successRetention applies after a successful completion, while errorRetention applies after an errored or terminated instance. That makes it possible to preserve diagnostic evidence without retaining every successful payload for the maximum period.
Reconcile the first billed usage window
After August 10, compare a consistent post-change window with the same dimensions in your implementation. Separate the Workflows metrics from ordinary Workers usage: a high request count, high CPU time, high step count, and high retained state have different remedies.
Use this sequence:
- Choose the billing window. Record the start and end timestamps, account plan, and code revision. Do not compare a partial day with a full month.
- Read the account data. Use the dashboard and invoice as the source of truth for what Cloudflare recorded; use the pricing page to explain the dimensions and allowances.
- Reconcile the model. Compare invocations, step paths, CPU-heavy callbacks, and average retained state with the same period in your estimate.
- Investigate the largest mismatch. A difference can come from loops, retries, long retention, or a second entry point rather than from the number of
step.do()calls in one file.
A practical audit after the billing start date
Use this order for an existing project once you have a complete usage window:
- Confirm the account plan. The new step and storage charges affect Workers Paid usage; do not mix the Free allowances with a Paid forecast.
- List entry points. Include scheduled triggers, webhooks, Worker bindings, CLI calls, and batch creation paths.
- Measure real runs. Compare dashboard activity with your expected invocation and step counts over the same period.
- Separate the four dimensions. Keep requests, CPU time, steps, and storage in separate columns.
- Inspect state size and retention. Look at sleeping and completed instances, not just currently running ones.
- Change one boundary at a time. If you reduce retained data or move an artifact to R2, verify retries, error inspection, and human-in-the-loop waits before changing step structure.
- Recheck after the change. Keep the dashboard window and the code revision together so a later cost comparison has context.
The goal is not to make every Workflow shorter. It is to know which workflows are high-frequency, which ones keep large state, and which failures or loops distort the expected path. That gives you an auditable basis for deciding whether a code change is worth the operational trade-off.
FAQ
Q: Will Cloudflare Workers Free charge for Workflows steps and storage?
A: Cloudflare’s published Workflows pricing includes 3,000 steps per day and 1 GB-month of storage on Workers Free, and says Free users will not be charged for steps or storage beyond those included amounts. Requests, CPU time, and other products still need to be checked separately.
Q: Does step.sleep() use CPU time while a Workflow is waiting?
A: No. Cloudflare says a Workflow waiting on an API response, paused by step.sleep(), or otherwise idle does not incur CPU time. The waiting instance can still contribute to persisted state, so inspect storage and retention separately.
Q: Do retries and rollback handlers count as billed steps?
A: Cloudflare’s Workflows pricing page says step count does not include rollback handlers or retries. Retries can still affect execution time, requests, and failure behavior, so a cost review should not treat the step count as the only signal.
References:
Cloudflare Workflows billing changelog
Report a typo or broken link, or suggest a related topic.