Blog/LLMOps & Evals
LLM-Batch-APIs: Inferenz zum halben Preis für Arbeit, die warten kann
Wann sich die Batch-APIs von Anthropic, OpenAI und Gemini lohnen, wie Limits, Zuordnung und Fehler funktionieren und wie sich Rabatte mit Caching addieren.
Balázs Csorba··9 Min. Lesezeit
- Batch API
- Cost
- LLMOps
- Prompt caching
- Data pipelines

Das Wichtigste in Kürze
- Anthropic, OpenAI und Gemini berechnen für Batch-Anfragen 50 % der Standardpreise, im Gegenzug kommen die Ergebnisse asynchron innerhalb eines 24-Stunden-Fensters.
- Ergebnisse kommen in beliebiger Reihenfolge zurück: immer über custom_id oder key den Quelldatensätzen zuordnen, nie über die Position.
- Batch-Limits sind ein eigener Topf neben den synchronen Limits, die Verlagerung von Backfills und Evals in Batches schützt also auch den interaktiven Verkehr.
- Batch- und Prompt-Caching-Rabatte addieren sich, aber Cache-Treffer im Batch sind Best Effort; identische cache_control-Blöcke verwenden und den 1-Stunden-Cache erwägen.
- Batch-Daten liegen wochenlang beim Anbieter: Anthropic hält Ergebnisse 29 Tage, OpenAI löscht Output-Dateien nach 30 Tagen, Gemini nach 6 Wochen.
Ein überraschend großer Teil der LLM-Ausgaben berührt nie einen Nutzer. Ein Support-Archiv nach einer Taxonomieänderung neu klassifizieren, Produkttexte für einen Katalogimport schreiben, eine nächtliche Eval-Suite laufen lassen, Dokumente nach einem Modellwechsel neu embedden: nichts davon braucht eine Antwort in zwei Sekunden, trotzdem schicken viele Teams es über denselben synchronen Endpunkt wie ihr Chat-Feature, zum vollen Preis und im Wettbewerb um dieselben Rate-Limits.
Genau für diese Arbeit gibt es Batch-APIs. Man reicht viele Anfragen auf einmal ein, der Anbieter verarbeitet sie, wenn er Kapazität hat, und man holt innerhalb von 24 Stunden eine Ergebnisdatei zum halben Preis ab. Dieser Leitfaden vergleicht die Angebote von Anthropic, OpenAI, Gemini und Bedrock und zeigt dann, was sich im Code ändert: Zuordnung der Ergebnisse, Teilausfälle, Caching, Limits, Datenaufbewahrung und wann OpenAIs Flex-Tier die einfachere Option ist.
Welche Workloads in einen Batch gehören
Der Test ist einfach: würde es jemand merken, wenn das Ergebnis morgen früh statt jetzt käme? Anthropics eigene Liste der Einsatzfälle umfasst großangelegte Evaluationen, Content-Moderation, Datenanalyse und Massenerzeugung von Inhalten wie Produktbeschreibungen. Typische Kandidaten in meinen Projekten:
- Katalogpflege. Beschreibungen, Attributextraktion und Übersetzungen für Tausende SKUs nach einem PIM-Import, siehe Pimcore-ERP-Delta-Sync.
- Eval-Läufe. Regressionssuiten mit Hunderten Fällen pro Prompt-Version, bei denen ein Ergebnis in einer Stunde reicht; siehe LLM-Evals für Produktfeatures.
- Backfills. Historische Tickets, Bestellungen oder Dokumente nach einer Schema- oder Taxonomieänderung klassifizieren oder zusammenfassen.
- Embeddings und Moderation. OpenAI-Batches decken
/v1/embeddingsund/v1/moderationsab; Gemini hat einen eigenen Batch-Aufruf für Embeddings.
Was nicht passt: alles, worauf ein Nutzer wartet, und Agentenschleifen, deren Tools im eigenen Code laufen. Jede Batch-Anfrage ist ein Modellzug, ein Agent, der ein Client-Tool aufruft, braucht also für jeden Schritt eine neue Anfrage. Serverseitige Tools sind anders: bei der Claude API laufen Websuche, Web-Fetch und Code-Ausführung im Batch-Worker, der pro Zug mehr Schleifendurchläufe macht als ein synchroner Aufruf, bevor er pausiert.
Anthropic, OpenAI, Gemini und Bedrock im Vergleich
| Aspekt | Anthropic | OpenAI | Gemini | Bedrock |
|---|---|---|---|---|
| Preis | 50 % des Standards | 50 % weniger | 50 % des Standards | Siehe Bedrock-Preise |
| Pro Batch | 100.000 Anfragen oder 256 MB | 50.000 Anfragen, 200-MB-Datei | 20 MB inline, 2-GB-Datei | Kontingente pro Konto |
| Fenster | 24 h, meist unter 1 h | 24 h, fest | 24 h Ziel | Asynchroner Job |
| Eingabe | JSON-Anfrageliste | Hochgeladene JSONL-Datei | Inline oder JSONL-Datei | JSONL in S3 |
| Zuordnungsschlüssel | custom_id | custom_id | key | recordId |
| Ergebnisse verfügbar | 29 Tage | Output nach 30 Tagen gelöscht | 6 Wochen | Eigener S3-Bucket |
Einige Einschränkungen übersieht man leicht. Eine OpenAI-Eingabedatei kann nur ein Modell ansprechen. Bedrock-Batch-Jobs im Converse-Format können kein Tool-Calling nutzen; dafür braucht man das InvokeModel-Format mit dem nativen Request-Body des jeweiligen Modells. Und bei der Claude API werden stream, der Fast-Mode-Parameter speed und max_tokens: 0 im Batch abgelehnt; fast alles andere, auch Bilder, Tool-Nutzung und die meisten Beta-Features, funktioniert.
Der Lebenszyklus eines Batches
Bei der Claude API startet ein neuer Batch mit processing_status gleich in_progress und wechselt auf ended, wenn jede Anfrage fertig ist; Ergebnisse lassen sich herunterladen, sobald alle Nachrichten fertig sind oder nach 24 Stunden, je nachdem, was zuerst eintritt. OpenAI hat mehr Zustände: validating, failed bei ungültiger Eingabedatei, in_progress, finalizing, completed, expired, cancelling und cancelled. Gemini verwendet JOB_STATE_*-Werte von pending bis expired. Bedrock kann statt Polling über EventBridge benachrichtigen.
Anfragen bauen, die man zuordnen und wiederholen kann
Anthropic und OpenAI weisen beide darauf hin, dass Ergebnisse nicht in Eingabereihenfolge zurückkommen müssen, und raten, über custom_id zuzuordnen. Diese ID deterministisch machen: aus Quelldatensatz und Prompt-Version ableiten, damit ein erneuter Lauf dieselbe ID erzeugt und der Schreibprozess upserten kann statt zu duplizieren. Bei der Claude API muss sie ^[a-zA-Z0-9_-]{1,64}$ entsprechen, rohe SKUs mit Schrägstrichen oder Punkten scheiden also aus.
import hashlib, time, anthropic
client = anthropic.Anthropic()
PROMPT_VERSION = "desc-v7"
def cid(sku: str) -> str: # deterministic, safe characters, <= 64 chars
return f"{PROMPT_VERSION}-{hashlib.sha1(sku.encode()).hexdigest()[:20]}"
requests = [{
"custom_id": cid(p["sku"]),
"params": {
"model": "claude-sonnet-5-5",
"max_tokens": 800,
"system": [{"type": "text", "text": STYLE_GUIDE, # identical in every request
"cache_control": {"type": "ephemeral", "ttl": "1h"}}],
"messages": [{"role": "user", "content": render_product(p)}],
},
} for p in products]
batch = client.messages.batches.create(requests=requests)
while client.messages.batches.retrieve(batch.id).processing_status != "ended":
time.sleep(60)
retry = []
for r in client.messages.batches.results(batch.id):
if r.result.type == "succeeded":
upsert_description(r.custom_id, r.result.message) # idempotent write
else: # errored, canceled, expired
retry.append(r.custom_id)Die Validierung der params jeder Anfrage erfolgt bei der Claude API asynchron, ein Tippfehler in einem Feld zeigt sich also erst, wenn der ganze Batch beendet ist. Anthropic rät, eine Anfrageform vorher gegen die synchrone Messages API zu testen. Ich mache das im selben Skript: die erste Anfrage synchron senden, die Antwort gegen das Schema prüfen, dann den Rest einreichen.
Teilausfälle und was man bezahlt
Ein Batch gelingt oder scheitert nie einfach so. Bei der Claude API endet jede Anfrage als succeeded, errored, canceled oder expired, und nur die erste Art wird berechnet. Verfall ist nicht hypothetisch: Anthropic weist darauf hin, dass sich die Verarbeitung je nach Nachfrage und eigenem Anfragevolumen verlangsamen kann, dann verfallen mehr Anfragen nach 24 Stunden. OpenAI schreibt Erfolge in eine Output-Datei und Fehler in eine Fehlerdatei; verfällt ein Batch, bleiben fertige Anfragen verfügbar und werden berechnet, der Rest erscheint mit dem Code batch_expired.
- Fehlerklassen trennen. Validierungsfehler brauchen einen Code-Fix; Serverfehler und Verfall kommen unverändert in den nächsten Batch.
- Retry-Runden begrenzen. Zwei oder drei Neueinreichungen, dann die Datensätze für einen menschlichen Blick parken.
- Inhalt prüfen, nicht nur Status. Auch eine erfolgreiche Anfrage kann an
max_tokensstoßen oder JSON liefern, das am Schema scheitert, siehe strukturierte Ausgaben. - Sehr große Jobs aufteilen. Anthropic empfiehlt, große Datensätze auf mehrere Batches zu verteilen; das macht auch Fortschritt und Kosten pro Teil sichtbar.
Batch- und Prompt-Caching-Rabatte kombinieren
Batch-Jobs sind meist dieselben langen Anweisungen, angewendet auf viele Datensätze, die ideale Form für Prompt-Caching. Anthropic hält fest, dass sich Caching- und Batch-Rabatte addieren. Der Haken: Batch-Anfragen laufen parallel und in beliebiger Reihenfolge, Cache-Treffer sind also Best Effort; Anthropic nennt typische Trefferquoten zwischen 30 % und 98 %, je nach Verkehrsmuster. Die Empfehlung lautet, in jede Anfrage identische cache_control-Blöcke zu setzen und, weil ein Batch länger laufen kann als die fünfminütige Cache-Lebensdauer, den Ein-Stunden-Cache zu erwägen. Auch Gemini unterstützt Context Caching für Batch-Anfragen zu den normalen Caching-Preisen.
Vorher nachrechnen. Der Write in den Ein-Stunden-Cache kostet das Doppelte des Input-Basispreises statt des 1,25-Fachen, er lohnt sich also nur, wenn das gemeinsame Präfix lang ist und der Batch groß genug, um es oft zu lesen. Zur Caching-Mechanik selbst siehe Prompt-Caching und Modell-Routing.
Limits, Durchsatz und Ausgaben
Batch-Verkehr hat auf beiden Plattformen eigene Limits, und das ist der halbe Sinn. Laut Anthropic beeinflusst die Nutzung der Batches API die Rate-Limits der Messages API nicht; stattdessen werden HTTP-Anfragen an die Batch-Endpunkte und die Zahl der in der Verarbeitungswarteschlange wartenden Batch-Anfragen begrenzt, modellübergreifend: 200.000 wartende Anfragen im Start-Tier, 300.000 im Build-Tier und 500.000 im Scale-Tier, höchstens 100.000 pro Batch. Die Batch-Limits von OpenAI sind ein eigener Topf, berechnet aus den wartenden Input-Tokens pro Modell, und man kann bis zu 2.000 Batches pro Stunde anlegen.
Für lange Ausgaben gibt es bei der Claude API eine reine Batch-Funktion: der Beta-Header output-300k-2026-03-24 hebt max_tokens bei der aktuellen Generation Opus, Sonnet und Haiku 5.5 und mehreren älteren Modellen auf 300.000, für Entwürfe in Buchlänge oder erschöpfende Extraktion. Eine einzelne Generierung dieser Größe kann über eine Stunde dauern und frisst damit am 24-Stunden-Fenster.
Wann Flex Processing die einfachere Wahl ist
OpenAI bietet einen Mittelweg. Wer bei einem Responses- oder Chat-Completions-Aufruf service_tier auf flex setzt, bekommt Batch-Preise für eine normale synchrone Anfrage, im Tausch gegen langsamere Antworten und gelegentliche Nichtverfügbarkeit. Fehlt Kapazität, kommt ein 429, der nicht berechnet wird, und man wartet und wiederholt oder sendet mit service_tier: auto zum Standardpreis erneut. Das Standard-Timeout des SDK beträgt zehn Minuten, OpenAIs Beispiele erhöhen es auf fünfzehn.
| Frage | Batch API | Flex Processing |
|---|---|---|
| Codeform | Datei einreichen, abfragen, Ergebnisse parsen | Normale Anfrage und Antwort |
| Preis | Batch-Preise | Batch-Preise |
| Fehlerbild | Verfallene oder fehlerhafte Zeilen im Ergebnis | 429 Resource Unavailable, nicht berechnet |
| Am besten für | Zehntausende unabhängige Anfragen | Niedrig priorisierte Arbeit in bestehenden Codepfaden |
Datenaufbewahrung und DSGVO
Asynchrone Verarbeitung heißt, dass der Anbieter Eingaben und Ausgaben speichert, bis man sie abholt. Anthropic hält Batch-Anfrage- und Antwortdaten bis zu 29 Tage nach Erstellung vor, erlaubt das Löschen eines fertigen Batches über DELETE /v1/messages/batches/{batch_id}, isoliert Batches pro Workspace und lässt den Ergebnis-Download in der Console abschalten; ob Zero Data Retention gilt, steht pro Feature auf der Seite zur Datenaufbewahrung. OpenAI löscht Output-Dateien 30 Tage nach Abschluss des Batches, Gemini hält Ergebnisse 6 Wochen vor, und Bedrock schreibt sie in einen S3-Bucket unter eigener Kontrolle.
Für personenbezogene Daten heißt das dreierlei: Batches löschen, sobald die Ergebnisse gespeichert sind, Anbieter und Region im Verzeichnis der Verarbeitungstätigkeiten führen und prüfen, ob die Aufbewahrungszusagen im Vertrag Batch-Speicher überhaupt abdecken. Das größere Bild steht in DSGVO-Datenresidenz für LLM-APIs; berührt ein Backfill Kundendaten, ihn vorher durch eine PII-Redaktion schicken.
Quellen
- Claude Platform Docs: Batch processing
- Claude Platform Docs: Rate limits (Message Batches API)
- Claude Platform Docs: Prompt caching
- OpenAI API Docs: Batch API
- OpenAI API Docs: Flex processing
- OpenAI API Docs: Rate limits (batch queue limits)
- Google AI for Developers: Gemini Batch API
- Amazon Bedrock User Guide: Batch inference
Häufige Fragen
Wie viel günstiger ist eine Batch-API?
Anthropic, OpenAI und Google Gemini berechnen für Batch-Anfragen 50 % der Standardpreise. Bei der Claude API gilt das für Input-, Output- und Sondertokens, Claude Opus 5.5 kostet im Batch also 2 Dollar pro Million Input-Tokens und 10 Dollar pro Million Output-Tokens. Rabatte durch Prompt-Caching kommen hinzu.
Wie lange dauert ein Batch?
Alle drei Anbieter arbeiten mit einem 24-Stunden-Fenster. Laut Anthropic sind die meisten Batches in weniger als einer Stunde fertig, aber Anfragen, die nicht innerhalb von 24 Stunden verarbeitet werden, verfallen. Pipelines für den ungünstigsten Fall von 24 Stunden planen, nicht für den typischen.
Kann ich Tools und strukturierte Ausgabe in Batch-Anfragen nutzen?
Bei der Claude API lässt sich fast jede Messages-Anfrage batchen, auch mit Tool-Nutzung, Server-Tools, Bildern, System-Prompts und mehrteiligen Gesprächen; stream, speed und max_tokens 0 werden nicht unterstützt. Client-Tools brauchen weiterhin einen Rundweg, jeder Tool-Aufruf bedeutet also eine neue Anfrage. Bei Bedrock braucht Tool-Calling das InvokeModel-Format statt Converse.
Was passiert mit fehlgeschlagenen Anfragen in einem Batch?
Jede Anfrage bekommt ein eigenes Ergebnis. Bei der Claude API werden errored, canceled und expired nicht berechnet. Bei OpenAI landen Fehler in einer eigenen Fehlerdatei, und verfällt ein Batch, bezahlt man die Anfragen, die fertig wurden. Die Fehlschläge sammeln und in einem neuen Batch erneut einreichen.
Batch-API oder OpenAI Flex Processing?
Flex ist eine synchrone Anfrage mit service_tier flex, zu Batch-Preisen, aber langsamer und manchmal nicht verfügbar; dann kommt ein 429, der nicht berechnet wird. Es passt zu Jobs, die einfachen Request-Response-Code wollen. Ein Batch passt zu großen Mengen, bei denen man auf eine Ergebnisdatei warten kann.