Zu viele Requests in kurzer Zeit können eine API ausbremsen, Kosten hochtreiben oder sogar zum Ausfall führen. Das passiert nicht nur durch Angriffe, sondern oft auch durch Bugs (z. B. ein Client, der bei einem Fehler in einer Endlosschleife erneut anfragt). API Rate Limiting sorgt dafür, dass eine Schnittstelle stabil bleibt: Sie begrenzt, wie viele Anfragen in einem Zeitraum akzeptiert werden.
Wichtig ist dabei die Balance: Ein zu strenges Limit nervt echte Nutzer:innen, ein zu lockeres Limit schützt nicht. Entscheidend sind klare Regeln, sinnvolle Antwortcodes und ein Setup, das sich im Betrieb gut beobachten lässt.
Wann Rate Limiting wirklich nötig ist
Rate Limiting ist nicht nur ein „Security-Extra“, sondern häufig ein Stabilitäts- und Kostenwerkzeug. Besonders sinnvoll ist es in diesen Situationen:
- Public APIs oder Endpunkte, die ohne Login erreichbar sind
- Login-, Passwort-Reset- und OTP-Endpunkte (Schutz vor Ausprobieren/Brute Force)
- Teure Operationen: Reports, Exporte, komplexe Such- oder Aggregationsabfragen
- Traffic-Spitzen durch Marketing, Bots oder Crawling
- Integrationen mit Drittsystemen, die selbst Limits haben
Auch interne APIs profitieren: Wenn ein Service plötzlich mehr Requests erzeugt (z. B. nach einem Deploy), fängt ein Limit das Problem früh ab und schützt Downstream-Systeme.
„Zu viele Requests“ ist nicht gleich Angriff
Typische harmlose Ursachen sind: Clients ohne Backoff (sie warten nicht zwischen Retries), schlecht konfigurierte Cronjobs, doppelte Event-Auslieferungen oder Frontends, die bei jeder Eingabe sofort eine Suche auslösen. Ein gutes Rate Limiting verhindert, dass solche Fehler eskalieren, und liefert gleichzeitig klare Signale an Client-Teams.
Welche Strategien es gibt – und wann welche passt
Es existieren mehrere Verfahren, um Anfragen zu zählen und zu begrenzen. Sie unterscheiden sich vor allem darin, wie „fair“ sie sich bei Spitzen verhalten und wie gut sie in verteilten Systemen funktionieren.
Feste Zeitfenster (Fixed Window)
Hier wird pro Zeitfenster gezählt, z. B. „100 Requests pro Minute“. Vorteil: sehr einfach. Nachteil: Am Fensterwechsel können Bursts entstehen (kurz vor und kurz nach der Minute jeweils 100 Requests).
Geeignet für grobe Limits, einfache Admin-Tools oder interne APIs, bei denen ein Burst nicht kritisch ist.
Gleitendes Zeitfenster (Sliding Window)
Statt starrer Minuten wird über die letzten X Sekunden/Minuten gemessen. Das ist fairer, weil es Burst-Spitzen am Fensterwechsel abmildert. Die Umsetzung ist etwas komplexer (oft über Zeitstempel-Listen oder eine „rolling“ Berechnung).
Geeignet, wenn Limits spürbar sein sollen, aber nicht „sprunghaft“ wirken dürfen.
Token Bucket (empfohlen für viele APIs)
Beim Token Bucket gibt es einen „Eimer“ mit Tokens. Pro Request wird ein Token verbraucht. Tokens füllen sich mit einer festen Rate wieder auf, bis ein Maximum erreicht ist. Dadurch sind kurze Bursts erlaubt (wenn noch Tokens da sind), dauerhaftes Dauerfeuer wird aber begrenzt.
Das Modell ist gut verständlich und fühlt sich für Nutzer:innen fair an: Wer kurzzeitig mehr macht, wird nicht sofort blockiert, solange es nicht dauerhaft ist.
Leaky Bucket und Queueing
Leaky Bucket kann man sich wie einen Trichter vorstellen: Requests „tropfen“ konstant durch. Statt Bursts zu erlauben, glättet es den Durchsatz. In Kombination mit einer Queue kann das sinnvoll sein, wenn Requests nicht sofort beantwortet werden müssen (z. B. Importjobs). Für klassische HTTP-APIs ist das aber oft unnötig kompliziert.
Kurzer Vergleich für die Auswahl
| Verfahren | Stärken | Typische Schwächen |
|---|---|---|
| Fixed Window | Einfach, schnell | Burst am Fensterwechsel |
| Sliding Window | Fair, gleichmäßiger | Komplexer in der Umsetzung |
| Token Bucket | Bursts erlaubt, langfristig stabil | Benötigt State (Zähler/Token) |
| Leaky Bucket | Sehr gleichmäßiger Output | Für HTTP oft Overkill |
Was genau wird limitiert? Schlüssel, Scope und Prioritäten
Die wichtigste Designfrage lautet: „Pro wen“ gilt das Limit? Dafür braucht es einen Schlüssel (Key). Häufige Varianten:
- Pro IP-Adresse (einfach, aber bei NAT/VPN nicht immer fair)
- Pro User-ID (besser bei Logins, aber erfordert Authentifizierung)
- Pro API-Key/Client-ID (ideal für Partner-APIs)
- Pro Endpunkt (z. B. streng bei /login, lockerer bei /health)
- Kombinationen, z. B. pro User und pro Endpunkt
Globales Limit plus feinere Regeln
In der Praxis helfen zwei Ebenen:
- Ein globales Limit als „Airbag“, der extreme Peaks abfängt
- Zusätzliche Limits pro sensiblen Endpunkt (Login, Passwort-Reset, Suchendpunkte)
Damit lässt sich verhindern, dass ein einzelner teurer Endpunkt das Gesamtsystem blockiert.
Prioritäten statt „hartem Nein“
Manche Systeme unterscheiden zwischen Prioritäten: Interne Systeme oder bezahlte Pläne bekommen höhere Limits, anonyme Requests niedrigere. Wichtig ist, das transparent zu gestalten, damit Client-Teams wissen, welches Verhalten erwartet wird.
Praktische Umsetzung: Wo Rate Limiting am besten sitzt
Rate Limiting kann auf mehreren Ebenen stattfinden. Welche Ebene ideal ist, hängt von Architektur und Betrieb ab.
Am Edge/Proxy (z. B. API Gateway, Reverse Proxy)
Vorteil: Entlastet die Anwendung früh und schützt auch vor Traffic, der die App sonst nie erreichen sollte. Nachteil: Regeln sind manchmal weniger kontextreich (z. B. User-ID erst nach Auth bekannt).
In der Anwendung (Middleware)
Vorteil: Sehr flexibel, Zugriff auf Auth-Informationen, Endpunkte, Rollen, Abos. Nachteil: Die App bekommt den Traffic erst einmal ab, was bei extremen Peaks trotzdem belastet.
State: In-Memory vs. zentral (Redis o. Ä.)
In einer einzelnen Instanz kann ein In-Memory-Zähler reichen. In verteilten Setups (mehrere App-Instanzen) muss der Zähler geteilt werden, sonst kann jede Instanz ihr eigenes Limit erlauben. Typisch ist ein zentraler Store wie Redis.
Die „So geht’s“-Box: Limits definieren, kommunizieren, testen
- Schlüssel festlegen: IP, User-ID oder API-Key – und ggf. pro Endpunkt kombinieren.
- Strategie wählen: Für viele APIs ist Token Bucket ein guter Startpunkt.
- Antwortverhalten festlegen: Bei Überschreitung sauber HTTP 429 (Too Many Requests) zurückgeben.
- Client-Hinweise mitsenden: sinnvolle Header/Infos, ab wann wieder Requests akzeptiert werden.
- Beobachtbarkeit einbauen: Zähler für „blocked requests“, Top-Keys, betroffene Endpunkte.
- Lasttests fahren: Limits unter realistischen Peaks prüfen (auch Retries simulieren).
Antworten und Fehlersignale: Was Clients brauchen
Wenn ein Limit greift, sollte die API nicht „mysteriös“ wirken. Das Ziel ist, dass Clients korrekt reagieren: langsamer werden, später erneut versuchen oder den Nutzer informieren.
Statuscode und Retry-Informationen
Üblich ist HTTP 429. Zusätzlich ist es hilfreich, einen klaren Hinweis zu geben, wann ein Retry Sinn ergibt (z. B. in Form von „Retry-After“ oder einer vergleichbaren Information). Welche Header genau verwendet werden, hängt vom Setup ab – wichtig ist vor allem Konsistenz.
Fehlertext klar und stabil halten
Ein guter Response enthält eine kurze, stabile Maschinenbotschaft (z. B. error code) und eine verständliche Erklärung. Vermeidenswert sind wechselnde Texte, die Client-Teams zu Sonderfällen zwingen.
Zusammenspiel mit allgemeiner Fehlerbehandlung
Rate Limiting ist nur ein Baustein. Eine robuste API behandelt auch andere Fehler sauber, inklusive sinnvoller Statuscodes und konsistenter Fehlerobjekte. Dazu passt der Beitrag API-Fehler richtig behandeln – robuste Webanwendungen.
Typische Stolperfallen im Betrieb
Viele Probleme entstehen nicht durch die Idee des Limitierens, sondern durch Details in der Umsetzung.
Limits ohne Backoff: Clients erzeugen erst recht Last
Wenn ein Client bei 429 sofort erneut anfragt, entsteht ein „Retry-Sturm“. Besser: Exponentielles Backoff (nach jedem Fehlschlag länger warten) und ggf. Zufall (Jitter), damit nicht alle Clients gleichzeitig wiederkommen.
NAT und geteilte IPs
Bei IP-basierten Limits können viele Nutzer:innen hinter derselben IP hängen (Firmen, Mobilfunk). Dann trifft das Limit die Falschen. Abhilfe: IP-Limit nur als grobe Schutzschicht, und zusätzlich user-/key-basierte Limits nutzen.
Verteilte Systeme ohne gemeinsamen Zähler
Wenn mehrere Instanzen zählen, aber nicht synchron sind, werden Limits „weich“ und unzuverlässig. Hier hilft ein zentraler Store oder ein Gateway, das die Limits vor der Anwendung durchsetzt.
Zu wenige Informationen im Monitoring
Ohne Metriken bleibt unklar: Sind die Limits zu streng? Gibt es einen Bug-Client? Welche Endpunkte sind betroffen? Praktisch sind Dashboards für blockierte Requests, Top-Keys und Zeitverläufe. Ergänzend hilft sauberes Logging, etwa wie in Structured Logging – Logs im Backend sinnvoll strukturieren.
Mini-Fallbeispiel: Login-Endpunkt vor Ausprobieren schützen
Ein Login-Endpunkt ist ein Klassiker: Er ist öffentlich und wird häufig automatisiert ausprobiert. Eine sinnvolle Kombination ist:
- Ein strengeres Limit pro IP für /login (Stoppt massenhaftes Probieren)
- Ein Limit pro Account-Identifikator (z. B. E-Mail), um gezieltes Ausprobieren zu bremsen
- Klare 429-Responses, damit legitime Clients nicht „wild“ retryn
Wichtig: Rate Limiting ersetzt keine Auth-Sicherheit. Tokens, Sessions und sichere Implementierung gehören dazu. Dazu passt als Hintergrund JSON Web Tokens verstehen – Aufbau, Risiken, Best Practices.
Entscheidungshilfe: Welcher Weg ist für welches Projekt sinnvoll?
- Ist die API öffentlich erreichbar?
- Ja: Globales Limit am Edge plus feinere Regeln in der App einplanen.
- Nein: In der App starten, später bei Bedarf ans Edge ziehen.
- Gibt es mehrere Instanzen/Autoscaling?
- Ja: zentralen Zähler nutzen (z. B. Redis) oder Gateway-Limits.
- Nein: In-Memory kann für den Start reichen, aber später migrierbar halten.
- Sind kurze Bursts ok (z. B. UI lädt mehrere Ressourcen gleichzeitig)?
- Ja: Token Bucket wählen.
- Nein: Sliding/Leaky-Ansatz prüfen.
Wartung: Limits als Produktentscheidung behandeln
Rate Limits sind keine „einmal einstellen und vergessen“-Sache. Sie sollten wie ein Teil des Produkts gepflegt werden:
- Änderungen versionieren und kommunizieren (z. B. im Changelog)
- Grenzfälle beobachten: Welche Clients laufen häufig ins Limit?
- Grenzwerte regelmäßig prüfen, wenn Features oder Zielgruppen wachsen
- Sensitive Endpunkte separat behandeln
Wenn die API außerdem versioniert wird, lassen sich Regeländerungen sauberer einführen. Als Ergänzung passt API Versioning verstehen – Änderungen ohne Breaking Changes.
Quellen
- —

