Cloudflare Workflows step.sleep and a Sume job: poll without steps

Cloudflare Workflows step.sleep does not count toward the step limit, so a Sume job poll loop can wait cheaply. Limits, a loop shape and the retention catch.

4 min readSume
All posts

Yes: in Cloudflare Workflows, step.sleep does not count toward the step limit, so a loop that sleeps between Sume status checks costs steps only for the checks themselves. The limits page lists a sleep maximum of 365 days, 10,000 steps by default on Paid (configurable to 25,000) and 1,024 on Free. Use a webhook as the primary signal and the sleeping loop as the backup.

Limits that shape the design

These come from the Workflows limits reference and the Workflows changelog.

Cloudflare Workflows limits (read 2026-10-02)
LimitFreePaid
Steps per instance1,02410,000 default, 25,000 configurable
Max step.sleep365 days365 days
Concurrent instancesSee limits page50,000, waiting excluded
Instance creation rateSee limits page300 per second
Step result size1 MiB1 MiB
State retention3 days30 days, default 7 for new instances

A loop that does not burn steps

Create the Sume job inside one step.do, returning only the job id, which is tiny against the 1 MiB result limit. Then loop: step.sleep for the number of seconds Sume gave in next_poll_after_seconds, then step.do to read GET /v1/jobs/:id/status. Each status read is one step, so a job that needs a few checks stays far below the cap.

Make the create step idempotent. Workflows retry failed steps, and a retried create without a key can make a second paid job. Send an Idempotency-Key derived from the instance id so a replay returns the original.

  • Store the job id, not the result URL contents.
  • Fetch /result after the state is terminal, and write large output to storage rather than returning it from a step.
  • Stop at a sensible total wait and mark the run for review instead of looping for days.

The retention catch

A long sleep is only useful if the instance still exists when it wakes. Retention is 3 days on Free and 30 days on Paid, with a 7 day default on new Paid instances since September 10. Keep the Sume job id somewhere durable, because job results can be fetched by id later while the Workflows state may be gone.

Webhook first, sleep second

Sume pushes job.completed, job.failed and job.canceled with up to 10 attempts. A Worker route can write the terminal state to storage on receipt. The sleeping poll then only fires if the push never arrived. Dedupe on job_id so both paths are safe to run.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume