Von 1K auf 10K Requests pro Sekunde zu skalieren ist nicht die größere Version desselben Problems — es ist ein anderes Problem. Die Architektur, die ein Jahr lang unauffällig gelaufen war, degradierte bei 10x nicht graceful; sie versagte in Modi, die unsere Dashboards nie zuvor gezeigt hatten.

Was bei 1K RPS funktionierte:

  • Synchrone Service-zu-Service-Aufrufe mit Default-Timeouts
  • Datenbank-Joins für komplexe Abfragen
  • Vollständige Debug-Logs nach CloudWatch, kein Sampling
  • Einfaches Round-Robin-Load-Balancing

Der erste Bruch: Connections

Bei 1K RPS hielten wir rund 120 Datenbank-Connections gegen ein PostgreSQL-max_connections von 500 — komfortabel. Jenseits von 4K RPS verdreifachte der Autoscaler die Pod-Zahl, jeder neue Pod öffnete seinen eigenen Pool mit 20 Connections, und wir erreichten die Obergrenze innerhalb von Minuten. Queries stauten sich, die Latenz stieg, und alle vorgelagerten Services liefen in Timeouts. Dieser Fehlermodus ist so häufig, dass er seinen eigenen Bericht bekommt: der Autoscaler, der unsere Datenbank gekillt hat.

Der zweite Bruch: kaskadierende Timeouts

Unsere Aufrufkette war API → orders → pricing → inventory, jeder Hop mit 30 Sekunden Default-Timeout und drei Retries. Als inventory langsamer wurde, wiederholte jeder Hop darüber seine Aufrufe und verdreifachte so den Traffic pro Ebene ungefähr — ein Retry-Sturm, der die p99-Latenz von 80 ms auf über 10 Sekunden trieb, während Worker-Threads blockiert dasaßen und auf eine Abhängigkeit warteten, die bereits am Ertrinken war.

Der dritte Bruch: die Observability-Rechnung

Das Log-Volumen skaliert linear mit dem Traffic: 10x Requests bedeuteten 10x CloudWatch-Ingestion, und Logging wurde still und leise unser zweitgrößter Infrastrukturposten. Wir gingen dazu über, Logs auf Debug-Level mit 1% zu sampeln — für uns richtig, weil das bei 10K RPS immer noch rund 100 Debug-Events pro Sekunde liefert, reichlich, um einen Incident zu diagnostizieren. Errors und Warnings werden nie gesampelt. Sampling ist für Events mit hohem Volumen und wenig Signal; die richtige Rate ist eine Funktion Ihres Traffics, keine universelle Konstante.

Neue Patterns nötig:

  • PgBouncer-Connection-Pooling plus Read Replicas
  • Timeout-Budgets: Deadlines entlang der Kette propagiert, Retries gedeckelt und mit Jitter versehen
  • Queue-gestützte Writes, um Bursts abzufangen, statt synchronem Fan-out
  • Rate Limiting am Edge, bevor Requests den Anwendungscode erreichen
  • Key-Splitting für Hot Keys im Cache — der Session-Key eines einzigen Tenants machte ein Drittel der Operationen auf einem einzelnen Redis-Shard aus

Die Erkenntnis:

In jeder Größenordnung lösen Sie andere Probleme. Die Architektur, die bei 1K funktioniert, überlebt 10K nicht, und das 10K-Design trifft bei 100K auf neue Fehlermodi. Der einzige bezahlbare Weg, die Ihren früh zu finden, sind Lasttests bei 10x, bevor echter Traffic das für Sie erledigt — die Art Übung, die wir als ständige Praxis in Delivery-Pipelines und Release Engineering einbauen, nicht als Einmalaktion.

Lektion: Skalierungstests sind nicht optional. Ihr 10x-Traffic-Tag findet jede Schwachstelle — die einzige Frage ist, ob Sie sie zuerst finden.


← Zurück zu Lessons Learned

Incidents wie dieser sind vermeidbar. Unser AWS Managed Services-Team überwacht Kundenumgebungen 24/7 mit KI-gestütztem Monitoring und Senior Engineers am Pager — damit Geschichten wie diese im Archiv bleiben.