Zum Inhalt springen
Projekt besprechen

26. Oktober 2026

Retry ohne Jitter ist halb gelöst

APIsLLMEngineering

Warum sofortiges Wiederholen schadet

Ein Fehler bedeutet nicht automatisch, dass die nächste Anfrage sofort Erfolg haben wird. Besonders bei einem Rate Limit oder einer vorübergehend überlasteten API kann ein unmittelbarer neuer Versuch die Lage verschärfen: Der Client erzeugt zusätzliche Last, während der Server bereits signalisiert hat, dass er nicht mehr Kapazität hat.

Dieses Muster wird kritisch, wenn viele Prozesse denselben Fehler nahezu gleichzeitig sehen. Ohne abgestimmte Wartezeit senden sie erneut zur gleichen Zeit. Aus einem einzelnen Engpass kann so ein Retry-Sturm werden. Das betrifft klassische APIs ebenso wie LLM-Dienste, deren Kapazität oder Anfragekontingente begrenzt sein können.

Ein robuster Rate Limit Retry ist deshalb keine Endlosschleife mit catch und sofortigem Neuversuch. Er braucht Regeln dafür, wann, wie oft und für welche Operationen erneut angefragt wird.

Exponentielles Backoff: Zeit zwischen Versuchen erhöhen

Exponentielles Backoff vergrößert die Wartezeit mit jedem weiteren Versuch. Statt immer nach derselben kurzen Pause erneut anzufragen, wächst die Verzögerung schrittweise.

Ein typisches Schema beginnt mit einer Basiswartezeit und verdoppelt diese pro Versuch. Bei einer Basis von 250 Millisekunden wären denkbare Verzögerungen 250, 500, 1.000 und 2.000 Millisekunden. Die konkreten Werte sind keine allgemeine Vorgabe; sie müssen zur Operation, zum Timeout und zu den Erwartungen des aufrufenden Systems passen.

Backoff nimmt Druck vom Zielsystem und gibt ihm Zeit zur Erholung. Zugleich verhindert es, dass ein einzelner Client in kurzer Zeit unverhältnismäßig viele identische Anfragen erzeugt.

Jitter verhindert den Gleichschritt

Backoff allein löst nicht alles. Wenn viele Clients mit derselben Basiszeit starten und dieselbe Formel nutzen, warten sie auch gleich lang. Danach senden sie wieder gleichzeitig. Das Problem verschiebt sich lediglich in die Zukunft.

Jitter fügt eine zufällige Streuung zur Wartezeit hinzu. Die Clients klopfen dadurch nicht im Gleichschritt erneut an. Das ist der entscheidende Teil von Retry Backoff Jitter.

Ein einfaches Muster ist Full Jitter: Zuerst wird ein Backoff-Limit berechnet, dann wird zufällig eine Wartezeit zwischen null und diesem Limit gewählt. Zusätzlich begrenzt ein Cap die maximal mögliche Verzögerung.

function retryDelayMs(attempt: number): number {
  const baseMs = 250;
  const maxMs = 8_000;
  const backoffLimit = Math.min(maxMs, baseMs * 2 ** attempt);
  return Math.floor(Math.random() * backoffLimit);
}

Dieses Beispiel beschreibt nur die Wartezeit. Es entscheidet noch nicht, ob ein Fehler überhaupt wiederholt werden darf.

Retry-After hat Vorrang

Wenn ein Server einen Retry-After-Header liefert, enthält dieser eine konkrete Anweisung zum nächsten Versuch. Diese Information sollte der Client beachten, statt nur seine lokale Backoff-Formel anzuwenden.

Praktisch heißt das: Den Header parsen, eine gültige Wartezeit übernehmen und auch diese Wartezeit mit einer maximal erlaubten Dauer begrenzen. Fehlt der Header oder ist er nicht sinnvoll interpretierbar, kann der lokale Backoff mit Jitter greifen.

Die Reihenfolge ist damit klar: Serverhinweis berücksichtigen, sonst eine eigene, gestreute Wartezeit berechnen. Ein Retry-After ersetzt allerdings nicht die übrigen Schutzmaßnahmen. Auch mit Serverhinweis bleiben eine Versuchszahl, ein Zeitbudget und Idempotenz relevant.

Obergrenzen machen Fehler beherrschbar

Jeder Retry-Mechanismus braucht ein Ende. Sinnvoll sind mindestens zwei Grenzen:

  • eine maximale Anzahl von Versuchen
  • eine maximale Wartezeit oder ein gesamtes Zeitbudget

Nach Erreichen einer Grenze sollte die Operation sauber scheitern. Der Aufrufer braucht dann einen eindeutigen Fehler statt eines Prozesses, der unbemerkt weiter wartet oder weiter Last erzeugt. Je nach Architektur kann anschließend eine Queue, ein späterer manueller Vorgang oder eine gezielte Fehlerbehandlung übernehmen.

Wichtig ist außerdem eine Auswahl der wiederholbaren Fehler. Nicht jede Antwort und nicht jeder Netzwerkfehler bedeutet dasselbe. Dauerhafte Fehler, etwa ungültige Eingaben oder fehlende Berechtigungen, werden durch Wiederholen in der Regel nicht besser.

Idempotenz vor dem Wiederholen prüfen

Der gefährlichste Retry ist eine Anfrage, die auf dem Server bereits erfolgreich ausgeführt wurde, deren Antwort aber beim Client nicht angekommen ist. Wiederholt der Client sie blind, kann die Aktion doppelt stattfinden.

Idempotente Anfragen sind dafür ausgelegt, bei mehrfacher Ausführung denselben fachlichen Endzustand zu erzeugen. Solche Anfragen sind deutlich besser für Retries geeignet. Ist eine Operation nicht idempotent, sollte sie nicht pauschal wiederholt werden.

Falls eine API einen Idempotency-Key unterstützt, kann der Client denselben Schlüssel bei allen Wiederholungen derselben fachlichen Operation senden. Der Server kann damit doppelte Ausführungen erkennen und behandeln. Der Schlüssel muss dabei an die Operation gebunden bleiben, nicht an jeden einzelnen Netzwerkversuch.

Robustes Retry-Verhalten entsteht nicht durch eine einzelne Formel. Backoff reduziert Druck, Jitter verhindert Synchronisation, Retry-After respektiert den Server, Obergrenzen begrenzen Schäden und Idempotenz schützt vor doppelter Ausführung.

Prüft euren Retry-Code: Backoff, Jitter, Retry-After, Obergrenze, Idempotenz. Was fehlt?