Eine PHP-Anwendung auf Spitzenlast vorzubereiten bedeutet nicht, die übliche Besucherzahl mit einem beliebigen Faktor zu multiplizieren. Die erforderliche Kapazität hängt davon ab, wie viele Anfragen gleichzeitig eintreffen, wie lange jede einzelne dauert und welche Arbeit sie ausführt: Eine gecachte Seite und ein Vorgang, der mehrere externe Dienste abfragt, verbrauchen nicht dieselben Ressourcen.
Das operative Ziel besteht darin, herauszufinden, welche Komponente den Dienst unter repräsentativer Last begrenzt, wie viel Spielraum vorhanden ist und was zu tun ist, wenn dieser Spielraum erschöpft ist. Tests liefern eine Entscheidungsgrundlage, garantieren aber keine universelle Kapazität, denn das Ergebnis hängt von Code, Infrastruktur, Daten und dem tatsächlichen Nutzungsmuster ab.
Last nach Gleichzeitigkeit und Vorgangstyp einschätzen

Das tägliche oder monatliche Volumen reicht für die Dimensionierung nicht aus. Eine Anwendung kann viele Besuche über Stunden verteilt erhalten und dabei reichlich Spielraum haben oder Anfragen auf wenige Minuten konzentrieren und überlastet werden. Um die Belastung abzuschätzen, beobachte die Ankunftsrate, die Dauer der Anfragen und den Anteil gleichzeitig ausgeführter Vorgänge.
Als Orientierung gilt: Steigt die Dauer bei gleichbleibender Ankunftsrate, bleiben mehr Anfragen gleichzeitig aktiv. Deshalb kann eine langsame Abhängigkeit die Gleichzeitigkeit erhöhen, selbst wenn sich der eingehende Traffic nicht ändert. Auch der Traffic kann ungleich verteilt sein: Eine Kampagne kann Produktseiten und Suchanfragen in die Höhe treiben, während ein Periodenabschluss Authentifizierungen, Exporte oder Schreibvorgänge konzentriert.
Ermittle zunächst die Routen und Vorgänge, die sich auf die Geschäftsziele auswirken. Berücksichtige beispielsweise öffentliche Navigation, Suche, Anmeldung, Auftragserstellung und relevante Verwaltungsaufgaben. Unterscheide Lese- von Schreibvorgängen, cachefähige von nicht cachefähigen Anfragen sowie synchrone Anfragen von Aufgaben, die in einer Queue verarbeitet werden könnten. Verwende nicht den globalen Durchschnitt, um eine langsame oder kritische Route zu verschleiern.
Einen repräsentativen und sicheren Test erstellen
Leite ein oder mehrere Szenarien aus verfügbarer Telemetrie, Zugriffsprotokollen und dem Kalender bekannter Ereignisse ab. Dokumentiere, welcher Anteil der Anfragen auf die einzelnen Vorgänge entfällt, wie sich die Ankunftsrate verändert und wie lange jede Phase dauert. Es empfiehlt sich, sowohl eine anhaltende Last als auch einen schnellen Anstieg zu testen, da sie unterschiedliche Verhaltensweisen aufdecken: die allmähliche Erschöpfung von Ressourcen gegenüber einer abrupten Reaktion auf eine Spitze.
Der Test sollte in einer Umgebung ausgeführt werden, die der Produktionskonfiguration ausreichend nahekommt, damit die Ergebnisse aussagekräftig sind. Prüfe Unterschiede bei der Anzahl der Prozesse, Verbindungsgrenzwerten, Caches, Datenmengen und Abhängigkeiten. Wird ein Test auf einer isolierten Maschine mit kleinen Tabellen ausgeführt, belegt das nicht, wie sich die Produktionsumgebung verhalten wird. Erzeuge keine Last gegen echte Nutzer ohne ausdrücklichen Plan und entsprechende Genehmigung.
Berücksichtige den Datenschutz bereits beim Entwurf des Szenarios. Verwende synthetische oder anonymisierte Daten, eigens dafür vorgesehene Zugangsdaten und minimale Berechtigungen; kopiere keine personenbezogenen Daten in Lasttest-Tools, wenn keine geeignete Rechtsgrundlage und keine angemessenen Kontrollen bestehen. Verhindere, dass Tests E-Mails versenden, Zahlungen auslösen oder unumkehrbare Folgen haben. Verwende für externe Vorgänge Testumgebungen oder kontrollierte Ersatzsysteme und beachte, dass ein Ersatzsystem nicht zwingend die Latenz oder Grenzwerte des echten Dienstes nachbildet.
Latenz, Fehler und Auslastung gleichzeitig messen
Erfasse die Latenz pro Route und beobachte Perzentile wie p50, p95 und p99. Der Durchschnitt kann stabil bleiben, während ein Teil der Anfragen sehr langsam wird; Perzentile machen diese Verteilung am oberen Ende besser sichtbar. Miss außerdem Fehlerrate, Timeouts und die Zahl der pro Zeiteinheit abgeschlossenen Anfragen. Ein Test, der viele Anfragen erzeugt, dabei aber auch viele Fehler verursacht, weist keine nutzbare Kapazität nach.
Setze diese Messwerte mit Ressourcen und Queues in Beziehung. Beobachte in PHP die Auslastung und die Queue der Prozesse, die Anfragen bedienen, sowie CPU, Arbeitsspeicher und Neustarts. Wenn du PHP-FPM verwendest, prüfe dessen Prozesskonfiguration und -metriken sowie die des Webservers; die verfügbare Metrik hängt von der Instrumentierung ab. Miss in der Datenbank aktive Verbindungen, Wartezeiten beim Verbindungsaufbau, langsame Abfragen, Sperren sowie CPU- und Festplattenauslastung. Beobachte ebenso Caches, Queues und externe Abhängigkeiten.
Lege Grenzwerte fest, die sich an Nutzererlebnis und Betrieb orientieren, nicht nur an der CPU-Auslastung. Für eine Kaufroute können beispielsweise vereinbarte Höchstwerte für Latenz und Fehlerrate gelten, während ein nicht kritischer Export Wartezeiten oder asynchrone Verarbeitung zulässt. Stelle sicher, dass Uhren und Beobachtungsfenster vergleichbar sind und du einen Latenzanstieg der Komponente zuordnen kannst, die ausgelastet war.
Den ersten Engpass finden, bevor du skalierst
Achte auf das erste Signal, das sich bei schrittweise steigender Last verschlechtert. Wächst die Queue der Webprozesse und bleibt die CPU-Auslastung von PHP hoch, kann das auf rechenintensive Arbeit pro Anfrage oder zu wenige verfügbare Prozesse hindeuten. Warten Prozesse auf Verbindungen, während die Datenbank noch Kapazität hat, solltest du die Pool-Grenzwerte oder die Verbindungskonfiguration prüfen. Zeigt die Datenbank langsame Abfragen, Sperren oder Überlastung, kann das Hinzufügen von PHP-Prozessen den Druck erhöhen und das Problem verschlimmern.
Auch externe Abhängigkeiten können Prozesse blockieren. Prüfe Verbindungs- und Antwortzeiten, Ratenbegrenzungen und das Verhalten bei Fehlern. Ein zu langer Timeout hält Ressourcen belegt; unbegrenzte Wiederholungsversuche können die Last vervielfachen. Lege begrenzte Timeouts und eine gezielte Retry-Strategie fest, gegebenenfalls mit zunehmenden Wartezeiten, und wiederhole nicht idempotente Vorgänge nicht automatisch ohne Schutzmaßnahmen.
Unterscheide Kapazitätsmangel von Ineffizienz. Eine Abfrage, die zu viele Zeilen durchläuft, wiederholte Aufrufe desselben Dienstes oder redundante Berechnungen bleiben auch nach dem Hinzufügen von Servern teuer. Profiliere repräsentative Routen und reduziere die Arbeit pro Anfrage: Optimiere Abfragen und Indizes auf Grundlage von Messwerten, begrenze Ergebnisse, entferne unnötige Aufrufe und nutze Caching, sofern Konsistenz und Datenschutz es zulassen. Wiederhole anschließend den Test, um zu prüfen, ob die Verbesserung auch unter Last Bestand hat.
Schrittweise eingreifen und kontrollierte Degradierung planen
Reduziere zuerst den Aufwand pro Anfrage und korrigiere Abfragen oder Abhängigkeiten, die den Engpass verursachen. Prüfe anschließend die Grenzen für Gleichzeitigkeit, die Webprozesse und die Verbindungspools. Mehr Prozesse können den Parallelismus erhöhen, bis CPU, Arbeitsspeicher oder Datenbank ausgelastet sind; mehr Verbindungen einzurichten, als die Datenbank bedienen kann, verlagert die Queue lediglich. Ändere jeweils nur eine Variable und miss erneut.
Vertikale Skalierung – mehr Ressourcen für eine Instanz – kann eine einfache Maßnahme sein, wenn die Komponente mitwachsen kann und keine strukturelle Grenze besteht. Horizontale Skalierung – mehr Instanzen – setzt voraus, dass Deployment, Sitzungen, Dateien, Aufgaben und Datenbank die Verteilung unterstützen. Prüfe Load-Balancing, gegebenenfalls gemeinsamen oder externen Speicher, den Zustand der Instanzen und gemeinsame Grenzwerte wie Datenbankverbindungen. Keine der Optionen behebt allein eine ineffiziente Abfrage.
Lege fest, was bei knapper Kapazität erhalten bleiben soll. Priorisiere je nach Produkt Authentifizierung, wesentliche Vorgänge oder Transaktionsbestätigungen; verschiebe Berichte, begrenze aufwendige Suchen oder deaktiviere vorübergehend entbehrliche Funktionen. Nutze Queues für Aufgaben, die später abgeschlossen werden können, und informiere Nutzer über den Status. Setze Ratenbegrenzungen oder Überlastungsantworten ausdrücklich und mit umsichtigem Wiederholungsverhalten ein. Eine kontrollierte Degradierung muss den Verlust bestätigter Vorgänge verhindern und eine verständliche Alternative bieten, statt einen Erfolg vorzutäuschen.
Damit die Tests zu einer operativen Entscheidung führen, dokumentiere Szenario, Konfiguration, Ergebnisse pro Route, den zuerst beobachteten Engpass, vorgenommene Änderungen und Abnahmekriterien. Wiederhole den Test nach Änderungen an relevantem Code, an der Infrastruktur, an Daten oder Abhängigkeiten. Bestätige vor einer erwarteten Lastspitze die Alarmierung, verfügbare Kapazität, Rollback-Verfahren und Zuständigkeiten für Entscheidungen.
Checkliste vor einer Lastspitze

- Szenario: Bildet plausible Routen, Anteile, Ankunftsraten und Dauer ab; umfasst einen schnellen Anstieg und eine anhaltende Last.
- Sicherheit: Verwendet geeignete Daten und Zugangsdaten, vermeidet unerwünschte reale Auswirkungen und kontrolliert das Testziel.
- Beobachtbarkeit: Setzt p95-/p99-Latenz und Fehler mit PHP-Prozessen, Datenbank, Cache und Abhängigkeiten in Beziehung.
- Diagnose: Ermittelt den ersten Engpass und bestätigt, ob er auf Überlastung, Abfragen, Gleichzeitigkeit oder externe Wartezeiten zurückzuführen ist.
- Änderung: Ändert jeweils eine Ursache, vergleicht die Ergebnisse und prüft, ob die Überlastung nicht auf eine andere Schicht verlagert wird.
- Resilienz: Legt Grenzwerte, Prioritäten, Degradierungen, Kommunikation und Wiederherstellung fest, ohne bestätigte Vorgänge zu verlieren.
- Wiederholung: Legt Abnahmekriterien fest und testet nach wichtigen Änderungen sowie vor absehbaren Ereignissen erneut.
Sorgfältige Dimensionierung bedeutet, das Verhalten der Anwendung in konkreten Szenarien zu kennen und mit ausreichendem Spielraum zu entscheiden, statt einer abstrakten Nutzerzahl nachzujagen. Messungen machen sichtbar, wo Investitionen nötig sind: bei der Optimierung, der Anpassung der Gleichzeitigkeit, zusätzlicher Kapazität oder einer Degradierungsstrategie, die wesentliche Funktionen weiterhin nutzbar hält.



