Blog/developers·3. Sept. 2026·6 Min.·vom eroq-Team
KI-Video in Produktion skalieren – Warteschlangen und Retries
KI-Video im großen Stil: asynchrone Jobs, eigene Warteschlange, Parallelität und Rate-Limits, Erstattungen, mehrere API-Schlüssel, signierte Webhooks.
Ein Clip ist eine Demo. Tausend Clips pro Woche sind ein Betriebsproblem, und was dabei kaputtgeht, steht nie in der Model Card. Es ist der Prozess, der mitten im Render neu gestartet ist, der Kunde, dem ein fehlgeschlagener Job berechnet wurde, und der Batch, der das Rate-Limit aufgefressen hat, das dein Live-Produkt gebraucht hätte.
So sieht eine Video-Pipeline aus, die Volumen übersteht. Die Formate sind die von eroq, dokumentiert unter /docs/video, aber die Überlegungen lassen sich auf jede asynchrone Medien-API übertragen.
Abschicken, nicht warten
Ein Video-Render dauert ein bis fünf Minuten. So lange sollte keine HTTP-Anfrage offen bleiben, deshalb ist der Endpoint asynchron: Der Aufruf bucht ab, startet den Render und antwortet sofort mit 202.
{
"id": "b7e6c2d4-…",
"object": "video.generation",
"status": "processing",
"created": 1756118400,
"model": "eroq-motion-one",
"duration": "5s",
"poll": "/v1/videos/generations/b7e6c2d4-…",
"usage": { "credits_spent": 100, "credits_remaining": 887 }
}
Speicher diese id, bevor du irgendetwas anderes tust – bevor du dem Aufrufer antwortest, bevor du loggst. Die Job-id ist der einzige Zugriff auf einen Render, den du schon bezahlt hast, und alles Weitere setzt voraus, dass sie in deiner Datenbank liegt und nicht in einer Variablen auf einer Maschine, die neu starten könnte.
Eine eigene Warteschlange
Du brauchst eine, und es sollte nicht die Warteschlange der API sein.
Die Nachfrage deiner Nutzer kommt in Schüben; die Render-Kapazität nicht. Ohne Puffer hast du zwei schlechte Optionen – Arbeit in Spitzenzeiten ablehnen oder parallele Anfragen auffächern, bis der Rate-Limiter sie abweist. Eine Warteschlange macht aus beidem eine Planungsentscheidung.
Die minimale Tabelle hat fünf Spalten, auf die es ankommt:
- Job-id aus der Antwort auf das Abschicken und Status, wie du ihn zuletzt gesehen hast
- die Request-Payload, damit ein erneutes Abschicken exakt denselben Render ergibt
- Anzahl der Versuche, damit ein Poison-Job nach drei Versuchen aufhört statt nie
- der Kunde oder die Kampagne, zu der er gehört, damit die Kosten auf dem richtigen Konto landen
- verbrauchte Credits, beim Abschicken aus
usage.credits_spentübernommen
Dazu ein Worker, der die Warteschlange in festem Takt abarbeitet, und eine zweite Schleife, die GET /v1/videos/generations/{id} für alles abfragt, was noch in Bearbeitung ist.
Für die Wiederherstellung nach einem Absturz gibt es einen Listen-Endpoint. GET /v1/videos/generations liefert jeden Job, den der Workspace in den letzten 24 Stunden abgeschickt hat – Renders von Teammitgliedern inklusive –, mit limit und einem status-Filter. Er enthält nie eingebettete Medien, eine Schleife darüber ist also günstig.
# what is still in flight right now
curl "https://eroq.ai/v1/videos/generations?status=processing&limit=50" \
-H "Authorization: Bearer $EROQ_API_KEY"
Wenn deine Datenbank und diese Liste sich widersprechen, hat die Liste recht.
Parallelität an den Rate-Limits ausrichten
Zwei verschiedene Zahlen, und sie zu verwechseln ist der übliche Fehler.
Die Abschickrate wird von der API begrenzt – 6 Video-Anfragen pro Minute und Schlüssel, multipliziert mit deinem Plan (2× Creator, 4× Studio, 6× Team, 8× Agency). Bilde sie in deinem Worker mit einem Token-Bucket ab.
Laufende Renders begrenzt nichts außer deiner Geduld und deinem Guthaben. Deckel sie trotzdem ausdrücklich – eine Obergrenze für laufende Renders verhindert, dass eine außer Kontrolle geratene Retry-Schleife an einem Nachmittag die Credits eines Monats verbrennt, und sie gibt dir eine Zahl, auf die du alarmieren kannst.
Stell den Bucket knapp unter das effektive Limit und lass die Warteschlange die Differenz auffangen – wie du mit einem 429 umgehst, wird unwichtig, wenn du selten einen auslöst.
Retries, Erstattungen und was du nicht wiederholen solltest
Das Abrechnungsmodell macht Wiederholen sicher: Credits werden beim Abschicken abgebucht, und ein Render, der fehlschlägt – oder nicht innerhalb von zehn Minuten fertig wird –, wird automatisch erstattet. Du gleichst gelieferte Clips ab, nicht Versuche.
Zwei weitere Garantien. Eine Anfrage, die die Inhaltsrichtlinie blockiert, liefert content_blocked und wird nie berechnet. Und die Prüfungen laufen vor der Abbuchung – ein Modell, das dein Plan nicht enthält, antwortet mit 403 plan_required, eine Engine, die gerade nicht verfügbar ist, mit 503 model_unavailable, beides, bevor sich ein einziger Credit bewegt, und keins von beiden weicht still auf eine andere Engine aus. Du bekommst das Modell, das du angefragt hast, oder einen Fehler – das einzige Verhalten, bei dem deine Ausgabe zu deinen Logs passt.
Die Retry-Strategie schreibt sich damit von selbst:
- Mit Backoff wiederholen –
429und Fehler auf Netzwerkebene, bei denen du nie eine Antwort gesehen hast. - Einmal wiederholen, dann die Engine wechseln –
503 model_unavailable. Halte eine Ausweich-Engine-id in der Konfiguration bereit, von dir ausgewählt, aus dem Angebot unter /models. - Nicht wiederholen, sondern melden –
402 insufficient_credits,403 plan_required,403 role_forbiddenund jedecontent_blocked-Ablehnung. Nichts davon ändert sich innerhalb eines Retry-Fensters von selbst. - Einen fehlgeschlagenen Render nicht mehr als zweimal automatisch wiederholen. Ein Prompt, der zweimal scheitert, scheitert meist auch ein drittes Mal, und dank der Erstattungen bezahlst du mit Latenz – und genau die sieht dein Kunde.
Ein erneutes Abschicken ist ein neuer Job mit neuer id, keine Wiederbelebung des alten – verknüpf beide ids in deiner Tabelle, sonst läuft deine Kostenrechnung pro Kunde auseinander.
Viele Schlüssel statt einem
Rate-Limits werden pro Schlüssel gezählt, Schlüssel sind also die natürliche Grenze für den Schadensradius. Die Pläne enthalten genau dafür ganze Schlüsselsätze – 10 Schlüssel bei Hobby, 20 bei Creator, 50 bei Studio, 100 bei Team, 200 bei Agency.
Eine vernünftige Aufteilung:
- ein Schlüssel pro Umgebung (Production, Staging, lokal),
- ein Schlüssel pro Pipeline in Production – der interaktive Pfad, auf den Nutzer warten, der nächtliche Batch-Pfad, der Pfad für interne Tools,
- und wenn du Generierung weiterverkaufst, einer pro großem Kunden, damit dessen Nutzung im Request-Log nachvollziehbar ist.
Schlüssel erben außerdem die Workspace-Rolle des Mitglieds, dem sie gehören – ein Offboarding ist also eine Rollenänderung statt eines Schlüssel-Audits. Der Tab „Mitglieder“ liegt unter /dashboard/workspace; die Kostenrechnung pro Kunde steht in Credit-Preise für KI-APIs.
Webhooks statt Polling
Polling ist bei zehn Renders pro Stunde in Ordnung und bei tausend Verschwendung. Registrier einen Endpoint und nimm stattdessen video.generation.succeeded und video.generation.failed entgegen.
Die Payload ist ein kleiner, signierter Umschlag – keine Megabytes an base64, die durch deinen Load Balancer wandern:
{
"id": "evt_9f21…",
"type": "video.generation.succeeded",
"created": 1756118400,
"data": {
"id": "b7e6c2d4-…",
"model": "eroq-motion-one",
"duration": "5s",
"content_type": "video/mp4",
"result_url": "https://store.eroq.ai/…/clip.mp4"
}
}
Die Zustellung trägt einen eroq-signature-Header im Stripe-Stil der Form t=<unix>,v1=<hex>, wobei der Hex-Wert ein HMAC-SHA256 von timestamp.body mit dem Endpoint-Secret ist, das beim Anlegen einmal angezeigt wird. Prüf ihn mit einem zeitkonstanten Vergleich, bevor du einem einzigen Byte traust, und lehn Zeitstempel ab, die mehr als ein paar Minuten danebenliegen, um Replays zu unterbinden.
Drei Regeln für den Handler, die dir Incidents ersparen:
- Schnell mit 2xx antworten, später arbeiten. Bestätigen, in die Warteschlange stellen, zurückgeben. Ein Handler, der inline ein Thumbnail rendert, läuft irgendwann in einen Timeout und lässt die Zustellung fehlgeschlagen aussehen.
- Zustellung als At-least-once behandeln. Verarbeite anhand der Job-id und mach die Verarbeitung idempotent.
- Polling als Untergrenze behalten. Ein Durchlauf über Jobs, die deine Datenbank noch für laufend hält, fängt alles auf, was ein Webhook verpasst hat. Und
result_urlistnull, wenn ein Clip eingebettet statt gespeichert zurückkam – behandle also auch diesen Zweig.
Batches – lass die Sequenz eine Ressource sein
Wenn du Sequenzen statt Einzelstücke renderst, bilde die Sequenz serverseitig ab, statt zwölf Abschickvorgänge selbst zu orchestrieren. Die films-Ressource von eroq speichert ein Storyboard, und POST /v1/films/{id}/render dreht jede Szene in einem Aufruf: Szenen werden einzeln abgerechnet, die Warteschlange läuft sequenziell, sodass ein leeres Guthaben den Durchlauf sauber stoppt, und die Antwort meldet pro Szene einen Job oder einen Fehler. Details unter /docs/films.
Teste die Pipeline auf einer günstigen Engine, bevor du eine teure nimmst – Seedance 1.0 Lite mit 120 Credits für fünf Sekunden macht einen End-to-End-Probelauf bezahlbar, und deine Warteschlange merkt keinen Unterschied. Die Plan-Freigaben stehen unter /pricing.
Häufige Fragen
Zahle ich für KI-Video-Renders, die fehlschlagen?
Nein. Credits werden beim Abschicken abgebucht, und ein Render, der fehlschlägt oder nicht innerhalb von zehn Minuten fertig wird, wird automatisch erstattet. Anfragen, die die Inhaltsrichtlinie blockiert, liefern content_blocked und werden nie berechnet.
Wie stelle ich Video-Jobs nach einem Neustart meines Servers wieder her?
Ruf GET /v1/videos/generations auf – das listet jeden Job, den der Workspace in den letzten 24 Stunden abgeschickt hat, mit seinem Status. Gleich das mit deiner eigenen Tabelle ab und behandle die Liste der API als maßgebliche Quelle.
Sollte ich bei der Videogenerierung pollen oder Webhooks nutzen?
Poll, solange du baust und das Volumen gering ist, und steig auf die Webhooks video.generation.succeeded und video.generation.failed um, sobald du ständig renderst. Behalte in jedem Fall einen langsamen Polling-Durchlauf als Sicherheitsnetz.
Bau zuerst die Warteschlange, dann die Pipeline – die Endpoint-Referenz steht unter /docs/video.
Mach das mit den Modellen hinter diesem Artikel – starte mit 50 Gratis-Credits oder sieh dir alle Engines und ihre Preise an.