Polling or webhook for 1,000 video jobs: count the requests

How many requests does a 1,000-job video batch need with polling or webhooks? A Python counter for poll schedules, plus Sume's per-plan read budgets.

4 min readSume
All posts

Polling a 1,000-job video batch every 2 seconds, with a 30-second cap on the delay, costs about 7 to 35 reads per job depending on how long it runs, 7,000 to 35,000 in total, while webhooks cost 1,000 inbound posts and zero reads. On Sume both fit inside the read budget of every plan, so the choice is about latency, simplicity and failure modes, not about the rate limit.

The budget you have

Sume gives each key a request budget per minute for all of /v1, with reads and writes counted separately. A read is any GET or HEAD, such as a poll of a status URL. Reads get forty times the write number in their own bucket, because Sume sized them for agents that hold many jobs open. That is why a tight status loop cannot cause a 429 on your own submits.

Per-minute budgets by plan (Sume docs, read 2026-10-05)
PlanWrites per minuteReads per minuteReads per second
Free1204,80080
Pro30012,000200
Startup60024,000400
Scale1,20048,000800

Count it

The schedule starts at 2 seconds and multiplies by 1.5 up to a 30-second cap. The function counts the polls for a job of a given length, then multiplies by the batch size. A 30-second Seedance 2.5 clip is an input you choose here, since render time depends on load, and a 4K Gemini Omni Flash 1.1 clip is another. Both lengths below are assumptions, to be replaced by your own measurements.

def polls_for(runtime_s: float, first: float = 2.0, factor: float = 1.5, cap: float = 30.0) -> int:
    t, wait, n = 0.0, first, 0
    while t < runtime_s:
        t += wait
        n += 1
        wait = min(wait * factor, cap)
    return n

JOBS = 1000
for label, runtime in [("short, 1 min", 60), ("medium, 5 min", 300), ("long, 15 min", 900)]:
    per_job = polls_for(runtime)
    total = per_job * JOBS
    print(f"{label}: {per_job} polls per job, {total} reads for {JOBS} jobs")

print("webhook: 0 reads, 1000 inbound posts, plus a sweeper of maybe 1 read per late job")

Reading the numbers

The count is modest: a 1-minute job needs 7 polls, a 5-minute job needs 15, and a 15-minute job needs 35. Over 1,000 jobs that is 7,000 to 35,000 reads spread across the whole run, which is a rounding error against a Pro plan's 12,000 a minute. So rate limits do not force you into webhooks. Poll when your service has no public endpoint, and keep the loop simple.

What polling does cost is latency and code. The average poll adds half a delay of lag, and at the 30-second cap that is about 15 seconds after the job finishes. A webhook delivers within moments of the terminal state.

How to choose

Both modes together is the robust answer. Google's own Omni docs poll a file state for large videos, and OpenRouter's video guide offers callback_url with signed payloads, so the two patterns are normal across vendors. On Sume, the docs recommend async polling or the webhook mode for new integrations and say a webhook is not your only recovery path.

  • Webhook plus a slow sweeper gives push speed and poll correctness.
  • Poll only when you cannot expose a public HTTPS endpoint. Sume rejects localhost and plain HTTP callbacks.
  • Use the next_poll_after_seconds hint on the jobs route when it is present.
  • Measure your own job times, then replace the three runtimes above.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume