API Rate Limiting mit Claude Code: Patterns & Best Practices 2026
📅 6. Mai 2026⏰ 10 min Lesezeit💻 TypeScript & Redis
Jede produktive API, die im Internet exponiert wird, benötigt einen soliden Rate-Limiting-Mechanismus.
Ohne ihn sind Dienste anfällig für Missbrauch, DDoS-Angriffe, unkontrollierte Kostenexplosion und
Serviceausfälle. Gerade KI-APIs wie Anthropics Claude Code API verursachen bei unkontrolliertem
Zugriff rapide Kosten.
In diesem Artikel zeigen wir die wichtigsten Rate-Limiting-Algorithmen, vergleichen sie anhand
konkreter Metriken und implementieren sie mit TypeScript, Redis und gängigen API-Gateway-Lösungen.
Alle Codebeispiele sind produktionsreif und direkt einsetzbar.
1. Rate Limiting Algorithmen im Vergleich
Nicht jeder Rate-Limiting-Algorithmus passt zu jedem Anwendungsfall. Die Wahl des richtigen
Algorithmus hängt von Faktoren wie Traffic-Muster, Burst-Toleranz, Speicherverbrauch und
der Genauigkeit der Limiterkennung ab. Hier ein strukturierter Vergleich der fünf
gängigsten Ansätze:
Fixed Window Counter
EINFACH
Der einfachste Ansatz: Für jedes Zeitfenster (z. B. 60 Sekunden) wird ein Zähler
hochgezählt. Erreicht der Zähler das Limit, werden weitere Anfragen abgelehnt.
Am Ende des Fensters wird der Zähler zurückgesetzt.
✓ Vorteile
Minimal Speicherverbrauch
Sehr einfach implementierbar
Performant (O(1))
✗ Nachteile
Burst am Fensterübergang (2x Limit)
Ungleichmäßige Verteilung
Nicht präzise für Hochlast
Sliding Window Log
PRÄZISE
Jede Anfrage wird mit Timestamp gespeichert. Beim neuen Request werden alle Einträge
außerhalb des gleitenden Fensters entfernt. Dann wird gezählt, ob das Limit überschritten ist.
Sehr präzise, aber speicherintensiv bei hohem Traffic.
✓ Vorteile
Exakt präzise
Kein Burst-Problem
Ideal für niedrigen Traffic
✗ Nachteile
Hoher Speicherverbrauch
O(n) bei Aufräumen
Schlecht skalierbar
Sliding Window Counter
EMPFOHLEN
Hybrid aus Fixed Window und Sliding Window Log. Kombiniert den aktuellen Fensterzähler
mit einem gewichteten Anteil des vorherigen Fensters. Bietet eine sehr gute Balance
zwischen Genauigkeit und Performance.
✓ Vorteile
Geringer Speicherverbrauch
Annähernd präzise
Produktionstauglich
✗ Nachteile
Leichte Ungenauigkeit
Komplexere Logik
Schätzung, nicht exakt
Token Bucket
BURST-TOLERANT
Ein virtueller Eimer wird mit Tokens gefüllt (mit konstanter Rate). Jede Anfrage
verbraucht einen Token. Ist der Eimer leer, wird die Anfrage abgelehnt oder verzögert.
Ideal für APIs, die kurze Bursts erlauben, aber einen Durchschnittsdurchsatz einhalten müssen.
✓ Vorteile
Burst-Traffic erlaubt
Flexible Konfiguration
Gut für Claude Code API
✗ Nachteile
State muss persistent sein
Refill-Timing kritisch
Distributed schwieriger
Leaky Bucket
KONSTANT
Anfragen füllen einen Eimer (Queue). Der Eimer "leckt" mit konstanter Rate — Anfragen
werden gleichmäßig verarbeitet. Überschreitet die Queue ihre Kapazität, werden neue
Anfragen abgewiesen. Erzwingt einen gleichmäßigen Ausgabestrom.
✓ Vorteile
Gleichmäßiger Output-Strom
Schützt Downstream-Dienste
Vorhersehbares Verhalten
✗ Nachteile
Kein Burst erlaubt
Latenz durch Queue
Requests können warten
Algorithmen-Vergleichsmatrix
Algorithmus
Speicher
Burst
Präzision
Empfehlung
Fixed Window
O(1)
✗ Problem
Niedrig
Einfache Dienste
Sliding Window Log
O(n)
✓ Kein Problem
Hoch
Low-Traffic APIs
Sliding Window Counter
O(1)
✓ Teilweise
Gut
Produktion ✓
Token Bucket
O(1)
✓ Erlaubt
Gut
KI-APIs ✓
Leaky Bucket
O(n Queue)
✗ Keiner
Exakt
Backend-Throttling
2. Token Bucket — TypeScript-Implementierung
Das Token-Bucket-Muster eignet sich besonders gut für KI-APIs wie Claude Code, weil es
kurze Bursts (z. B. beim Start einer Agentic-Session) erlaubt, während der Durchschnittsdurchsatz
kontrolliert bleibt. Hier eine vollständige TypeScript-Klasse mit In-Memory-State:
Die refill()-Methode wird lazy aufgerufen — nur wenn Tokens angefragt werden.
Das vermeidet unnötige Intervall-Timers und macht die Klasse thread-safe für Node.js (single-threaded).
Bucket Registry für Multi-User-APIs
In echten APIs benötigst du einen Bucket pro API-Key oder User-ID. Eine einfache Map-basierte
Registry mit automatischem Cleanup verwaltet die Buckets effizient:
Claude Code Empfehlung: Setze capacity = 20 und refillRate = 2
für Agentic-Sessions. Das erlaubt kurze Tool-Use-Bursts (bis 20 parallele Calls) bei einem
Steady-State von 2 Requests/Sekunde pro API-Key — passend zu Anthropics Rate Limits.
3. Redis Sliding Window mit Lua-Script
Für distributed APIs, bei denen mehrere Server-Instanzen gleichzeitig laufen, reicht
In-Memory-State nicht aus. Redis bietet die perfekte Basis für ein atomares Sliding-Window
durch ZADD, ZREMRANGEBYSCORE und ZCARD — alles
in einem atomaren Lua-Script.
Redis Sliding Window — Datenstruktur
REDIS
// Konzept: Sorted Set pro User-Key// Key: "rl:{userId}:{windowKey}"// Score: Unix-Timestamp in Millisekunden// Member: unique Request-ID (nanoid)// ZADD: Neuen Request eintragen// ZREMRANGEBYSCORE: Alte Requests außerhalb des Fensters entfernen// ZCARD: Aktuelle Anzahl zählen// EXPIRE: Key automatisch ablaufen lassen// Beispiel-State für User "user:abc" (100req/60s Limit):// Key: "rl:user:abc:60"// Members: [req_1714900001234, req_1714900023456, ...]// Scores: [1714900001234, 1714900023456, ...]
Atomares Lua-Script für Race-Condition-Sicherheit
Das kritischste Problem bei verteilten Rate Limitern ist die Race Condition zwischen
"prüfen" und "eintragen". Ein Lua-Script in Redis löst das atomar:
Lua-Script — Atomic Check-and-Increment
LUA ATOMIC
-- sliding_window.lualocal key = KEYS[1]
local now = tonumber(ARGV[1]) -- aktueller Timestamp (ms)local window = tonumber(ARGV[2]) -- Fenster in ms (z.B. 60000)local limit = tonumber(ARGV[3]) -- Max. Requests pro Fensterlocal request_id = ARGV[4] -- Unique ID für diesen Request-- 1. Alte Requests entfernen (außerhalb des Fensters)
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
-- 2. Aktuelle Anzahl prüfenlocal count = redis.call('ZCARD', key)
if count < limit then-- 3. Request eintragen
redis.call('ZADD', key, now, request_id)
-- 4. Key-Expiry setzen (2x Fenster als Sicherheit)
redis.call('PEXPIRE', key, window * 2)
return {1, limit - count - 1, 0} -- allowed, remaining, retryAfterelse-- 5. Ältesten Request finden → Retry-After berechnenlocal oldest = redis.call('ZRANGE', key, 0, 0, 'WITHSCORES')
local retry_after = 0if #oldest > 0then
retry_after = window - (now - tonumber(oldest[2]))
endreturn {0, 0, retry_after} -- denied, remaining=0, retryAfter(ms)end
In Node.js-Applikationen ist Express der Standard-Webserver. Mit express-rate-limit
und rate-limit-redis lässt sich ein produktionsreifer Rate Limiter in wenigen Zeilen
aufsetzen. Wichtig: Immer die richtigen HTTP-Headers setzen, damit Clients sauber reagieren können.
Wichtig: Ohne standardHeaders: true werden die standardisierten
RateLimit-* Headers (RFC 6585 / IETF Draft) nicht gesendet. Clients wie das
Claude Code SDK nutzen diese Headers für automatisches Retry-Backoff. Immer aktivieren!
5. Distributed Rate Limiting
Wenn dein Service horizontal skaliert — mehrere Pods in Kubernetes, mehrere
Lambda-Instanzen in AWS — reicht ein einzelner Redis-Node nicht mehr. Hier kommen
Redis Cluster, Redis Sentinel und alternative Lösungen ins Spiel.
Selbst mit Redis können Race Conditions auftreten, wenn das Lua-Script auf mehreren Nodes
läuft. Das klassische Problem: Zwei Pods fragen gleichzeitig an, beide sehen "99/100",
beide erlauben — effektiv 101 Requests.
Redlock-Algorithmus für kritische Limits
REDLOCK
import Redlock from'redlock';
// Redlock mit 3 unabhängigen Redis-Instanzenconst redlock = newRedlock(
[redisA, redisB, redisC],
{
driftFactor: 0.01,
retryCount: 3,
retryDelay: 200, // 200ms zwischen Versuchen
retryJitter: 50// Jitter verhindert Thundering Herd
}
);
asyncfunctioncriticalRateCheck(userId: string): Promise<boolean> {
const lockKey = `lock:rl:${userId}`;
awaitusing lock = await redlock.acquire([lockKey], 500);
// Kritischer Abschnitt — atomar unter Lockconst result = await rateLimiter.check(userId, 100, 60000);
return result.allowed;
// Lock wird automatisch freigegeben (using-Syntax)
}
// Hinweis: Redlock nur für sehr kritische Limits nutzen.// Lua-Script allein reicht für 99.9% der Fälle!
Fazit Distributed: Für die meisten APIs (bis ~10.000 req/s) reicht
ein einzelner Redis-Node mit Lua-Script. Redis Cluster ab ~50.000 req/s oder bei
Hochverfügbarkeitsanforderungen. Redlock nur für Limits mit absoluter Präzision
(Zahlungstransaktionen, Quotas mit Abrechnungsrelevanz).
6. API Gateway Integration (Kong, AWS, Nginx)
Wer Rate Limiting nicht im Applikationscode implementieren möchte, kann auf API-Gateway-Lösungen
setzen. Das verlagert die Limiterkennung vor den Applikationsserver und entlastet die
Backend-Infrastruktur vollständig.
Fazit: Die richtige Rate-Limiting-Strategie für 2026
Rate Limiting ist keine "Nice-to-have"-Funktion — es ist ein fundamentaler Sicherheits-
und Stabilitätsmechanismus für jede produktive API. Gerade bei KI-APIs wie Claude Code,
wo ein einzelner unkontrollierter Request erhebliche Kosten verursachen kann, ist ein
robustes Rate Limiting unverzichtbar.
Unsere Empfehlung für 2026:
Einzel-Server, kleines Team: express-rate-limit mit Redis Store
Multi-Tenant SaaS: Redis Sliding Window mit Lua-Script + Token Bucket pro User
Horizontale Skalierung (Kubernetes): Redis Cluster + Kong Plugin
Serverless / AWS-native: AWS API Gateway Usage Plans
Höchste Performanz: Nginx limit_req als erste Verteidigungslinie
Kombiniere immer Gateway-Level-Schutz (Nginx/Kong) mit Applikations-Level-Limits (Redis).
Das "Defense in Depth"-Prinzip sorgt dafür, dass selbst bei Bypass-Versuchen ein zweiter
Schutzwall greift.
Starte deinen KI-Agenten mit solidem Rate Limiting
SpockyMagicAI bietet KI-Automatisierungs-Infrastruktur mit eingebautem Rate Limiting,
Redis-Backend und Claude Code Integration — einsatzbereit in Minuten.