Polling 200 video jobs every 30 s is 400 calls a minute: do this

A poll loop copied to Sume's 30 s example turns 200 open jobs into 400 status calls a minute. Use next_poll_after_seconds, backoff, or a webhook plus sweep.

5 min readSume
All posts

If 200 video jobs are open and every one is polled every 30 seconds, you send 400 status requests a minute, about 6.7 a second, to learn almost nothing, because a video job takes minutes. The Sume docs give a 30-second sleep as an example interval; they also say to obey next_poll_after_seconds when the status payload has it, and to back off otherwise. A migrated Sora loop should do that instead of a fixed sleep.

The Sora Videos API stopped answering on 2026-09-24, per the Pondero report, so any poll loop you carry over is being rewritten anyway. Rewrite the interval first.

The arithmetic

Requests per minute is open jobs x 60 / interval. The table shows how fast a fixed interval multiplies, and what a slower one saves.

Status calls per minute for open video jobs at a fixed interval (read 2026-10-07)
Open jobsEvery 30 sEvery 60 sEvery 120 s
1020105
501005025
200400200100
5001000500250

What Sume says to do

On the jobs surface, the poll loop is GET /v1/jobs/{id}/status. Stop on completed, failed or canceled. The docs say to use exponential backoff and not to resubmit a paid request because a local timeout fired. On /v1/videos the same job answers at polling_url, with the statuses pending, in_progress, completed, failed, cancelled.

The jobs docs also say read, status and list endpoints can have their own rate limits, which they call poll backpressure rather than generation concurrency. Public responses can carry ratelimit-limit, ratelimit-remaining, ratelimit-reset and retry-after headers. When a 429 arrives, use retry-after if present. A poller that reads ratelimit-remaining can slow itself before it is throttled.

Three ways to cut the call count

  • Obey next_poll_after_seconds from the status payload when it is present. It is the server telling you when a check is worth making.
  • Use callback_url on /v1/videos, so a finished job notifies you; then poll only as a backstop, every few minutes, over jobs still open in your own table.
  • Group the sweep. One backstop pass over all open ids once every few minutes costs the same as a handful of fixed-interval polls.

What waiting mode does not do

mode: sync holds the submit call for at most 30 seconds and returns the same envelope. A video usually takes longer, so you get an unfinished job back and must poll anyway. The docs say not to resubmit in that case. Treat sync as an optimization for short jobs, not a way to avoid polling.

The practical setup is a webhook for the fast path and a slow sweep for the rest, with the sweep interval set from your own tolerance for a late video, not from the example in the docs.

A backoff that respects the server

A loop that fits the docs does three things per job. It reads the status. If next_poll_after_seconds is present it sleeps that long. If not, it doubles its own delay from a small start up to a ceiling you choose, and resets nothing on a transient 429: it waits retry-after and goes on. It stops on any terminal state and then reads the result once.

Keep the interval per job, not global. A job that has been queued for a while because the workspace is at its concurrency limit does not need the same cadence as one that just moved to processing. Queued is a normal state in Sume's admission model, so a long wait there is not a signal to resubmit.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume