MWCodebymw.de ↗
Terminal

429 bei KI-APIs richtig behandeln – Retry mit Exponential Backoff (Bash)

Jede KI-API (Claude, OpenAI, Gemini) drosselt mit HTTP 429, wenn du zu schnell anfragst. Wer sofort stur weiterhämmert, wird noch länger blockiert. So respektierst du den Retry-After-Header und wartest exponentiell.

Egal ob Claude, OpenAI oder Gemini – jede KI-API drosselt dich mit HTTP 429 (Too Many Requests), sobald du zu viele Anfragen pro Minute schickst. Der Fehler ist, dann sofort und stur weiter anzufragen: Das verlängert die Sperre nur. Richtig ist Exponential Backoff – nach jedem Fehlversuch doppelt so lange warten – und, wenn vorhanden, den Retry-After-Header respektieren, den der Server mitschickt.

Ein robuster Aufruf mit Retry

#!/usr/bin/env bash
set -euo pipefail

call_ai() {
  local url="$1" body="$2"
  local max=5 delay=2 attempt=1

  while : ; do
    # -w schreibt den HTTP-Status ans Ende, -D speichert die Header
    local resp status
    resp=$(curl -sS -w $'\n%{http_code}' -D /tmp/hdr \
      -H "x-api-key: ${ANTHROPIC_API_KEY}" \
      -H "anthropic-version: 2023-06-01" \
      -H "content-type: application/json" \
      -d "$body" "$url") || true

    status="${resp##*$'\n'}"        # letzte Zeile = Statuscode
    body_out="${resp%$'\n'*}"       # alles davor = Antwort

    if [ "$status" = "200" ]; then
      printf '%s\n' "$body_out"
      return 0
    fi

    # Nur 429 und 5xx sind wiederholbar – 400/401 sind echte Fehler
    if [ "$status" != "429" ] && [ "${status:0:1}" != "5" ]; then
      echo "Nicht behebbarer Fehler ($status): $body_out" >&2
      return 1
    fi

    if [ "$attempt" -ge "$max" ]; then
      echo "Aufgegeben nach $max Versuchen (letzter Status $status)" >&2
      return 1
    fi

    # Server-Vorgabe bevorzugen, sonst exponentiell warten
    local wait
    wait=$(grep -i '^retry-after:' /tmp/hdr | tr -dc '0-9' || true)
    wait="${wait:-$delay}"
    echo "Status $status – warte ${wait}s (Versuch $attempt/$max)" >&2
    sleep "$wait"

    delay=$((delay * 2))            # 2s, 4s, 8s, 16s …
    attempt=$((attempt + 1))
  done
}

call_ai "https://api.anthropic.com/v1/messages" \
  '{"model":"claude-sonnet-5","max_tokens":256,"messages":[{"role":"user","content":"Hi"}]}'

Die Regeln dahinter

  • Nur 429 und 5xx wiederholen. Ein 400 (kaputter Request) oder 401 (falscher Key) wird durch Warten nicht besser – sofort abbrechen und den Fehler melden.
  • Retry-After schlägt deine eigene Wartezeit. Wenn der Server sagt „komm in 12 Sekunden wieder", dann halte dich daran, statt schon nach 2 Sekunden erneut anzuklopfen.
  • Exponentiell, nicht linear. Verdopple die Wartezeit (2 → 4 → 8 → 16), damit sich viele parallele Clients nicht im Gleichtakt wieder gegenseitig blockieren. Ein bisschen Zufall („Jitter") obendrauf verteilt die Last zusätzlich.
  • Obergrenze setzen. Nach ein paar Versuchen aufgeben und sauber Fehler melden – sonst hängt dein Skript endlos.

Dasselbe Muster gilt für jede API mit Rate-Limits, nicht nur für KI. Die offiziellen SDKs von Anthropic und OpenAI machen genau das automatisch – gut zu wissen, wenn du selbst ohne SDK arbeitest.

Du willst eine KI-Integration, die auch unter Last stabil bleibt? Ich helfe dir weiter.

Quellen

#KI#Bash#Rate-Limit#Retry#API

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →