Clear a full Sume queue: cancel queued jobs after 429 queue_full

When submits fail with 429 queue_full, list queued jobs with GET /v1/jobs?status=queued and cancel the ones you no longer need. Safe on a 409, with a script.

4 min readSume
All posts

When submits start returning 429 queue_full, list your queued jobs with GET /v1/jobs?status=queued&limit=100 and send POST /v1/jobs/{id}/cancel for the ones you no longer need. Cancellation works only before generation starts, so a job that began in the meantime answers 409 job_generation_already_started and keeps running.

The Generation admission page lists this as the second step after you stop adding work: poll until at least one job is terminal, cancel queued jobs you do not need, then retry with the same idempotency key.

What the sweep may touch

A job belongs to the member whose key created it, and only that member can cancel it. An API key reads the jobs its own member created in the workspace, so the sweep cannot cancel a teammate's work. It also means a workspace that is full because of someone else's jobs will not be fixed by your sweep.

Responses to the cancel call (Jobs and results docs, read 2026-10-10)
SituationResponseYour move
Job still queuedCanceled job, terminalConfirm refund in the usage ledger if you need it.
Generation already started409 job_generation_already_started, details.cancelable falseLeave it; it completes or fails.
Already canceledSame canceled job (idempotent)Nothing.
Job not visible to this key404 not_foundSkip it.

The script

It lists one page of queued jobs, cancels each, and prints a short id with the outcome. The list is newest-first and capped at 100 per page; when data.next_cursor is present, pass it back as starting_after for the next page. The sample prints a notice instead of paging, because a sweep that cancels the newest hundred is usually a decision you want to make deliberately.

import json, os, urllib.error, urllib.request

def call(method, path):
    req = urllib.request.Request("https://api.sume.com" + path, method=method,
        headers={"x-api-key": os.environ["SUME_API_KEY"], "User-Agent": "sume-sweep/1.0"})
    try:
        with urllib.request.urlopen(req, timeout=30) as r:
            return r.status, json.load(r)["data"]
    except urllib.error.HTTPError as e:
        return e.code, json.load(e)["error"]

status, data = call("GET", "/v1/jobs?status=queued&limit=100")
for job in data["jobs"]:
    code, body = call("POST", f"/v1/jobs/{job['id']}/cancel")
    if code == 409:
        print(job["id"][:8], "not cancelable:", body["code"])
    else:
        print(job["id"][:8], "cancel ->", code)
print("more pages" if data.get("next_cursor") else "all queued jobs seen")

Before you run it

Decide which queued jobs are disposable. A sweep that cancels everything also cancels work that would have finished. Join on idempotency_key, which each job row carries, to cancel only a batch label you own, and not by array position.

After the sweep, re-read generation_limits on the next submit response. queue_capacity_remaining tells you how much room you bought, and the pacing formula max(0, concurrency_limit - active - queued) tells you how wide to go.

  • Cancel is a write; it spends the write budget, not the read one.
  • Do not cancel jobs that are processing; it will 409.
  • Keep the list call in a loop only if you can name the batch to cancel.

How big the queue is

Queue capacity is derived from the plan's concurrency: the larger of 3 or five times the concurrency limit. That makes it 5 for Free (1 running), 20 for Pro (4), 40 for Startup (8) and 100 for Scale (20), per the generation admission docs read 2026-10-10. Once running plus queued jobs fill it, the next submit gets 429 queue_full and nothing is charged for the refused request.

After you cancel, do not refill the queue in one burst. The generation_limits block reports queue_capacity_remaining and a wave_size_hint; submit one wave of that size, wait for slots, and repeat. That keeps the queue from filling again and the next queue_full from arriving.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume