Workflows createBatch: 100 instances, one per Sume job?
Cloudflare Workflows now creates up to 100 instances per call. Why a 100-job Sume wave fits only on Scale, and why to pass your own instance IDs.

Yes, you can start one Cloudflare Workflow per Sume job with the new createBatch() call, but give every instance its own ID and do not submit 100 paid jobs at once unless your plan accepts 120. Sume admits only as many paid jobs as concurrency + queue capacity, and on every plan except Scale that is fewer than 100.
Cloudflare's changelog entry dated 2026-10-08 (read 2026-10-10) says createBatch() can create "up to 100 Workflow instances in one call". It has two forms, and the form you pick decides whether you can join an instance back to a Sume job.
What the two createBatch forms do
The changelog describes a count form and a list form. In the count form you pass a count, and every instance gets identical configuration and an auto-generated ID. In the list form you pass an instances array, and each entry carries its own ID and its own parameters. The response has a created list and an errors array that explains failures.
For Sume work the list form is the one to use. A Sume submit returns a job id (request_id, shaped like job_...) in the first response in every communication mode. If that id becomes the Workflow instance ID, a later job.completed webhook can be routed to the right instance by id alone. With auto-generated IDs you would need a side table that maps instance to job.
| createBatch form | Instance ID | Per-instance params | Join back to a Sume job |
|---|---|---|---|
count | Auto-generated | Identical for all | Needs your own lookup table |
instances list | You choose, one per entry | Different per entry | Use the Sume job id or your own idempotency key as the ID |
Why 100 instances is not 100 accepted Sume jobs
The Workflows limit and the Sume limit are separate. Generation admission says Sume separates concurrency (jobs in processing), queue capacity (accepted, not yet started), submit rate limits and balance. When both concurrency and queue are full, a new paid submit fails with 429 queue_full.
The docs give the default numbers by plan. Accepted job capacity is concurrency_limit + queued_jobs_limit, which is the most paid jobs that can be processing or queued at the same time. The docs also say to prefer the effective generation_limits field over the static table, so read it before you size a wave.
| Plan | Processing | Queue capacity | Accepted at once | Room for a 100-instance batch? |
|---|---|---|---|---|
| Free | 1 | 5 | 6 | No: 94 would be refused |
| Pro | 4 | 20 | 24 | No: 76 would be refused |
| Startup | 8 | 40 | 48 | No: 52 would be refused |
| Scale | 20 | 100 | 120 | Yes, with 20 to spare |
A safer wave pattern
Treat the batch size as a cap, not a target. Size each createBatch() to the accepted capacity you read from generation_limits, minus the jobs already running. Each instance should submit its Sume job with an Idempotency-Key derived from the instance ID. The docs say a retry with the same key returns the original job and does not bill a second one, so a replayed Workflow step is safe.
Write budgets matter too. Authentication gives writes per minute by plan: 120 on Free, 300 on Pro, 600 on Startup and 1200 on Scale. A hundred submits are a hundred writes, and polls are reads with a separate, larger budget. A 429 rate_limited carries retry-after, and the docs tell you to wait that long.
- Pass
instanceswith your own IDs, one per Sume job or per input row. - Read
generation_limitsfirst and cap the batch at free accepted capacity. - Send
mode: "webhook"and keepstatus_urlpolls as a backup. - On
429 queue_full, back off and retry with the same idempotency key.
Handling errors and callbacks
The errors array in the createBatch response tells you which instances did not start. Retry only those entries, and keep the same IDs so a retry cannot create a duplicate instance for the same Sume job.
On the Sume side, Webhooks says delivery is up to 10 attempts, 30 seconds apart by default, with a 10 second timeout per attempt. Return a 2xx only after you store the event, and use job_id as the idempotency key. After the attempts run out the job still reached its real state, so keep the status poll as the recovery path. Redeliver re-sends a real terminal event with a fresh timestamp and signature.
Sources
Related posts
More in Integrations
- Cloudflare Workflows: sleep and poll a Sume run, no open request
A Cloudflare Workflow can submit a Sume run, step.sleep for minutes, then check status again. Here are the step limits that bound how long you can poll.
- Codex default_tools_approval_mode = writes for Sume MCP
Codex sets approval per MCP server and per tool. Which of auto, prompt, writes and approve suits Sume's read and paid tools, and what output_token_limit does.
- Cursor remote MCP has no envFile: where the Sume key goes
Cursor's envFile works for stdio servers only. For Sume's remote MCP, read the key from your shell with a headers entry, or skip keys and use OAuth.
- Docker Agent YAML: add Sume as a remote MCP toolset
Docker Agent takes a remote MCP URL, headers and a tools allowlist. Here is the Sume entry with a Bearer key from the environment and a read-only tool list.
Written by Sume