Inngest Bursty Concurrency 3x: will Sume answer queue_full?

Inngest can lift step concurrency 3x for 60 minutes a month. Sume's limit does not move: size bursts to accepted capacity and retry queue_full with one key.

4 min readSume
All posts

Yes, it can, but only when the burst is large enough to fill Sume's queue. Inngest's Bursty Concurrency changes how many of your steps run at once. It does not change how many generation jobs your Sume workspace accepts. Sume admits jobs up to its accepted job capacity (processing slots plus queue), and past that a submit returns 429 queue_full. Retry that with the same Idempotency-Key once a job finishes.

Inngest announced the feature on 2026-10-06. Per its changelog, when step concurrency goes over your account limit Inngest can raise the limit to 3x for up to 60 minutes a month, for Pro and above accounts.

What does a 3x burst do to a Sume workspace?

If each step submits one Sume job, a 3x burst triples the number of submits in flight. Sume's generation concurrency is plan-only, and top-ups do not raise it. Sume still accepts valid jobs as queued while queue capacity remains, so a burst is not an error by itself. The error only appears when the queue is also full.

Take an example in which your Inngest limit is 8 and the burst lifts it to 24 submitting steps. The table shows how each plan reacts if all 24 jobs arrive at once and nothing else is running.

Sume accepted job capacity by plan, from the generation admission page (read 2026-10-11)
PlanProcessingQueueAccepted capacity24 simultaneous jobs
Free15618 get queue_full
Pro42024All accepted
Startup84048All accepted
Scale20100120All accepted

How should a step handle queue_full?

Treat queue_full as backpressure, not as a failed job. Sume's docs say to wait for jobs to finish or cancel queued ones, then retry with the same idempotency key. Because Inngest retries a step with the same function run, build the key from your own order or run id, not from a fresh UUID per attempt. A replay with the same key and body is an exact retry. The same key with a different body gives 409 idempotency_conflict.

This sample submits a video job and retries on 429 using retry-after when it is present. Run it with Node 18 or later and SUME_API_KEY set.

const key = process.env.SUME_API_KEY;
if (!key) throw new Error("Set SUME_API_KEY");

async function submit(orderId: string) {
  const body = JSON.stringify({ model: "wan-3.0", prompt: "A red kettle steaming on a stove", duration: 5 });
  for (let attempt = 0; attempt < 6; attempt++) {
    const res = await fetch("https://api.sume.com/v1/videos", {
      method: "POST",
      headers: {
        "x-api-key": key!,
        "Content-Type": "application/json",
        "Idempotency-Key": `order-${orderId}-v1`,
      },
      body,
    });
    if (res.status !== 429) return { status: res.status, body: await res.json() };
    const wait = Number(res.headers.get("retry-after"));
    const seconds = Number.isFinite(wait) && wait > 0 ? wait : 2 ** attempt;
    await new Promise((r) => setTimeout(r, seconds * 1000));
  }
  throw new Error("still 429 after 6 attempts");
}

submit("8823").then((r) => console.log(r.status, r.body));

How do I size the burst instead of retrying blindly?

Submit responses carry generation_limits when Sume can compute it. Sume's guide suggests a budget of max(0, concurrency_limit - active_generation_jobs - queued_generation_jobs), capped at queue_capacity_remaining, and says to refresh the snapshot at zero headroom rather than keep submitting. Do not use wave_size_hint as a concurrency limit; it is only a submission-wave hint.

Two other limits are worth knowing. Reads and writes have separate request budgets, so polling status from many steps does not cause a 429 on your submits. A 429 names the budget in error.details.scope. And do not resubmit a paid job just because a step timed out; poll the job instead.

  • Cap the Inngest function's own concurrency at or below your Sume accepted capacity if you do not want burst submits to hit queue_full.
  • Use one stable idempotency key per business object, and store the job id the first time you see it.
  • Poll GET /v1/jobs/{id}/status with backoff, and stop on completed, failed, or canceled.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume