Bulk run worst-case spend: items x per-item cap on Sume
A Sume bulk run has no queue-level cap: each item carries its own generation_spend_cap_usd. 100 items at $120 can authorize up to $12,000. How to size it.

A bulk run submits up to 100 items against one Format, with concurrency between 1 and 16 and an optional idempotency_key. What it does not have is a queue-level spend cap: the Bulk runs docs put the cap on each item. That makes the maximum exposure a multiplication, not a setting.
The product ceiling on any one run is $500. A Format that never set a cap defaults to $400, and null means $500.
What can a bulk run authorize in the worst case?
The table multiplies items by the cap each carries. These are ceilings for planning, not predictions: a typical item finishes far below its cap, and the wallet is only charged for what each item generates. The docs describe production live-commerce integrations running with caps around $120.
| Items | Per-item cap | Worst case |
|---|---|---|
| 20 | $120.00 | $2,400.00 |
| 100 | $120.00 | $12,000.00 |
| 100 | $400.00 | $40,000.00 |
| 100 | $500.00 | $50,000.00 |
Why does the wallet matter more than the cap?
Each paid job reserves its estimated price when it is accepted, and a wallet that cannot cover the reserve returns 402 insufficient_credits. So the real limit on a large run is the balance you hold. A $500 wallet and a hundred items with $400 caps is safe because the wallet, not the caps, binds first, and the shortfall shows as 402s on later items rather than overspend.
Plan queue capacity as well. Accepted capacity is 6 on Free, 24 on Pro, 48 on Startup and 120 on Scale and Enterprise, so a 100-item run needs Scale to be accepted in one go; on Pro, the items beyond 24 can get 429 queue_full.
- Size per-item caps from your highest-priced step.
- Hold a wallet balance of at least concurrency x typical reserve.
- Use
idempotency_keyso a retried submit does not run twice.
A sizing rule
Set the per-item cap to roughly twice your measured typical item cost, then multiply by items and check that the result is a number you would accept losing. If it is not, shrink the batch or the cap. Re-running in batches of 24 on Pro costs nothing extra and gives you a natural checkpoint to read usage between rounds.
Sources
Related posts
More in Developers
- Bun 1.4.1 Bun.serve: a Sume webhook receiver on raw bytes
A Bun.serve routes handler that reads the request as bytes, verifies x-sume-webhook-signature, refuses an empty secret, and returns 2xx only after the check.
- Bun 1.4.1 Bun.write(path, response): save Sume artifacts to disk
Bun 1.4.1 streams a Response body to disk instead of buffering it. Read GET /v1/jobs/:id/result, then Bun.write each artifact URL, checking the status first.
- Bun.cron() for Sume jobs: an OS scheduler is not a job store
Bun 1.4 adds Bun.cron(), OS-level scheduling. Use it for a Sume reconcile pass over stored job ids, not as the place that remembers which jobs exist.
- Bun 1.4 fetch request compression: should Sume API calls use gzip?
Bun 1.4 can compress fetch request bodies. Sume's docs do not describe compressed requests, so leave it off and send media as public HTTPS URLs.
Written by Sume