Laravel-Performance systematisch analysieren statt blind optimieren

Von Nutzerwirkung und Tracing über SQL und Queues bis zum Lasttest: eine belastbare Reihenfolge für Performancearbeit.

Bei einer langsamen Laravel-Anwendung lautet die erste Frage nicht, welcher Cache fehlt. Zuerst muss klar sein, welcher Nutzerablauf langsam ist, wie häufig das Problem auftritt und wo die Zeit tatsächlich verbraucht wird. Ohne Messung optimiert ein Team leicht einen sichtbaren, aber unbedeutenden Teil des Systems.

Nutzerwirkung in eine technische Messung übersetzen

„Die Anwendung ist langsam“ kann sehr verschiedene Ursachen haben: hohe Serverantwortzeit, blockierte Queue, große Browser-Payload, langsame Drittanbieter-API oder eine Suche, die nur bei bestimmten Filtern kippt. Ein verwendbarer Problembericht nennt Route oder Job, Datengröße, Rolle, Zeitpunkt und erwartete Laufzeit.

Für Webanfragen sind mindestens p50, p95 und p99 hilfreich. Der Mittelwert versteckt einzelne sehr langsame Antworten. Bei Jobs zählen Durchsatz, Wartezeit, Laufzeit und Fehlerrate. Eine geschäftliche Kennzahl, etwa Dauer eines Imports oder Abschlussrate eines Prozesses, verhindert Optimierung ohne Nutzen.

Erst beobachten, dann verändern

Eine sinnvolle Analyse verbindet:

  • Request- und Job-Tracing,
  • langsame SQL-Abfragen und Query-Pläne,
  • Anzahl von Datenbankabfragen,
  • CPU, Arbeitsspeicher und I/O,
  • Queue-Länge und externe Laufzeiten,
  • Fehler und Wiederholungen.

Debug-Werkzeuge sind lokal nützlich, gehören aber nicht ungeschützt in die Produktion. In produktiven Umgebungen sollten Telemetrie und Logs so gefiltert werden, dass keine Passwörter, Tokens oder sensiblen Fachdaten aufgezeichnet werden.

Datenbankzugriffe mit Wirkung prüfen

Eloquent ist selten das eigentliche Problem. Teuer werden unklare Zugriffsmuster. Ein N+1-Problem erzeugt pro Datensatz weitere Abfragen. Fehlende Indizes zwingen die Datenbank zu großen Scans. Unbegrenzte Ergebnislisten verbrauchen Speicher und Übertragungszeit. Komplexe Aggregationen werden bei jedem Request neu berechnet.

Die Reihenfolge der Prüfung:

  1. langsame Abfrage mit realistischen Parametern erfassen,
  2. Ausführungsplan der Datenbank lesen,
  3. Selektivität und Reihenfolge möglicher Indizes bewerten,
  4. geladene Spalten und Beziehungen begrenzen,
  5. Ergebnis und Schreibkosten nach der Änderung erneut messen.

Ein zusätzlicher Index ist nicht kostenlos. Er benötigt Speicher und macht Schreibvorgänge teurer. Deshalb wird nicht nach Vermutung indexiert.

Arbeit aus dem Request verschieben

E-Mail, Bildverarbeitung, Exporte oder externe Synchronisation müssen häufig nicht innerhalb der Nutzeranfrage abgeschlossen werden. Queues verbessern die wahrgenommene Geschwindigkeit, wenn der fachliche Ablauf asynchron sein darf.

Der Job benötigt dann aber eigene Qualitätsmerkmale:

  • idempotentes Verhalten bei Wiederholung,
  • begrenzte Versuche und sinnvolle Wartezeiten,
  • eindeutige Fehlerzustände,
  • Monitoring für Warteschlange und fehlgeschlagene Jobs,
  • Schutz vor paralleler Bearbeitung desselben Objekts.

Ein Request wird nicht zuverlässig, nur weil seine langsame Arbeit unsichtbar im Hintergrund läuft.

Cache als Vertrag behandeln

Caching hilft bei teurer, häufig gelesener und ausreichend stabiler Information. Vor der Implementierung müssen Schlüssel, Mandantengrenze, Gültigkeitsdauer und Invalidierung feststehen. Besonders gefährlich ist ein Cache, der Daten zwischen Rollen oder Mandanten vermischt.

Frage Warum sie wichtig ist
Was ist der Cache-Key? Er muss alle fachlich relevanten Dimensionen enthalten.
Wer darf das Ergebnis sehen? Nutzer- und Tenant-Grenzen dürfen nicht verloren gehen.
Wann ist es veraltet? TTL und Ereignisse brauchen eine fachliche Begründung.
Was passiert bei Ausfall? Der Ursprung muss korrekt bleiben oder kontrolliert abbrechen.

Lasttests nach der Hypothese bauen

Ein Lasttest mit zufälligen Startseitenaufrufen beweist wenig. Er muss den problematischen Ablauf, realistische Datenverteilung und konkurrierende Aktionen abbilden. Für eine Suche sind häufige und seltene Filter relevant. Für einen Import zählen Dateigröße, Parallelität und nachgelagerte Jobs.

Vor und nach jeder Änderung werden dieselben Messwerte verglichen. Eine Verbesserung der Antwortzeit bei gleichzeitig steigender Fehlerrate ist kein Erfolg.

Ein Messprotokoll verhindert Erfolg nach Gefühl

Für jede Optimierung reicht ein kurzer, versionierter Datensatz. Er zwingt das Team, Ursache und Wirkung auseinanderzuhalten:

Feld Beispiel
Nutzerproblem Rechnungsübersicht benötigt bei großen Mandanten mehr als 3 Sekunden
reproduzierbare Last 50.000 Rechnungen, Rolle Buchhaltung, Filter „offen“
Ausgangswert p95 3,4 s, 142 SQL-Abfragen, 1,1 % Fehler
Hypothese eine nicht vorab geladene Beziehung erzeugt N+1-Abfragen
einzige Änderung gezieltes Eager Loading der drei dargestellten Spalten
Ergebnis p95, Query-Anzahl, Speicher und Fehlerrate erneut erfassen
Entscheidung übernehmen, zurückstellen oder nächste Hypothese testen

Der Messlauf verwendet dieselbe Datenbasis und dieselbe Parallelität. Zusätzlich wird mindestens eine geschäftliche Nebenwirkung geprüft, etwa korrekte Tenant-Filter oder vollständige Ergebnisse. Eine schnellere, aber fachlich falsche Abfrage ist eine Regression.

Ist die Anwendung noch nicht ausreichend verstanden, sollte vor der Optimierung die strukturierte Projektübernahme erfolgen. Berührt ein Cache Mandantengrenzen, liefert der Beitrag zu Mandantenfähigkeit und Berechtigungen die notwendigen Negativtests.

Quellen und Vertiefung

Fazit

Performancearbeit ist eine Folge überprüfbarer Hypothesen. Nutzerwirkung definieren, Laufzeit zerlegen, Engpass belegen, klein ändern und erneut messen. So wird aus „Laravel ist langsam“ eine konkrete technische Entscheidung mit sichtbarem Geschäftsnutzen.

Eine ähnliche Entscheidung steht in Ihrem Projekt an?

Schildern Sie den Kontext. Ich ordne die technischen Optionen, Risiken und einen sinnvollen nächsten Schritt ein.

Projektfrage besprechen ↗