Localized video batch: one Sume bulk queue per language

Split a multilingual batch into one Sume bulk queue per language so each language gets its own concurrency, spend cap, idempotency key and retry.

3 min readSume
All posts

Should one queue hold every language, or one queue per language?

A bulk queue holds 1 to 100 items, and each item has the same body as a single run, so a mixed-language queue is possible: every row simply carries its own language in input. But there are practical reasons to group by language instead.

A queue has one concurrency and one idempotency key, and it reports one set of counts. When all items share a language, a failure pattern is easy to read: if all 12 Korean items failed and the 12 Spanish ones passed, the problem is the Korean inputs or the Format's Korean handling, not luck.

What do I gain by splitting?

  • Independent retries: re-submit the Korean queue with a new key without touching the others.
  • Separate generation_spend_cap_usd per language, since some voices and captions cost more than others.
  • Different concurrency per queue, within your plan's generation concurrency of 1 on Free, 4 on Pro, 8 on Startup or 20 on Scale.
  • Keys that name the language, such as launch-42-ko, so a replay returns that language's queue and a changed payload is a 409.

How do I build the queues?

Pass the language as your own input key and let the Format's instructions read it. The first-party cookbook recipe reads a vo_language key; for your own Format, document the key you choose in its SKILL.md. Group rows by language, then submit one queue each:

from collections import defaultdict
import os, requests

URL = "https://api.sume.com/v1/formats/acme/launch-clip/bulk-runs"
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}

def submit_by_language(batch_id, rows, concurrency=4):
    groups = defaultdict(list)
    for row in rows:
        groups[row["language"]].append(row)
    queues = {}
    for lang, part in groups.items():
        body = {"concurrency": concurrency,
                "items": [{"input": r} for r in part[:100]]}
        r = requests.post(URL, json=body, timeout=30,
                          headers={**H, "Idempotency-Key": f"{batch_id}-{lang}"})
        r.raise_for_status()
        queues[lang] = r.json()["data"]["id"]
    return queues

What does the split not solve?

The ceiling per language is still 100 items, so a language with 140 rows needs two queues. Queues also share your workspace's wallet and concurrency, so five queues submitted together compete for the same slots. Check counts.failed on each, because completed only means every item is terminal.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume