Sume bulk item expires_at: 90 minutes start at dispatch, not at submit

A Sume run's expires_at is 90 minutes from created_at. A bulk child is created when dispatched, so a queued item's clock has not started.

3 min readSume
All posts

When does the 90-minute deadline start for a bulk item?

On a run receipt, expires_at is the deadline after which Sume force-finalizes a non-terminal run as failed. The runs docs put it 90 minutes after the run's created_at, or earlier if the run is older than 25 minutes and has been silent for 10. When the run is terminal, expires_at is null.

A bulk queue does not create all its child runs at submit time. It dispatches them as concurrency slots free up, and each child is created through the same path as a single run when it is dispatched. A queued item has run_id: null and no receipt, so no run clock is ticking for it. That follows from the code and docs together; the queue docs do not state a deadline for a queued item.

What does that mean for a 100-item queue?

With concurrency 4 and runs that take 10 minutes each, the last items wait roughly 240 minutes before they start, longer than 90, and that is fine, because their own 90 minutes begin when they dispatch. The ceiling applies per run, not to the whole batch.

Arithmetic from the documented 90-minute run deadline; the run time is an assumption, read 2026-10-04.
ItemsConcurrencyAssumed minutes per runRough queue wall time
100410250 minutes
100161070 minutes
1001101,000 minutes

What should my poller do?

Poll the queue, not just one run, and set your own timeout for the whole batch from the arithmetic above. Use each child's expires_at only as that run's ceiling, once it has a receipt. Do not invent a different per-run timeout.

Remember the earlier cutoff: a run silent for 10 minutes after passing the 25 minute mark can be finalized as failed before 90 minutes.

def queue_timeout_minutes(items, concurrency, minutes_per_run):
    waves = -(-items // concurrency)  # ceiling division
    return waves * minutes_per_run

print(queue_timeout_minutes(100, 4, 10))   # 250
print(queue_timeout_minutes(100, 16, 10))  # 70

What if the numbers are off?

Treat the estimate as a floor and add slack. A queue is completed only when every item is terminal, and a completed queue can still have counts.failed above zero.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume