Der Testaufruf am Montagvormittag sieht gut aus: Die Startseite antwortet in 400 Millisekunden, die Kategorieseite in 600, der Bericht ist grün. Sechs Wochen später, am Abend des ersten großen Kampagnentags, steht dieselbe Seite. Nicht weil sie über Nacht langsamer geworden wäre, sondern weil sie zum ersten Mal 300 Menschen gleichzeitig bedienen soll statt einer einzelnen Messsonde. 18,5 Prozent (HDE) seines Jahresumsatzes erzielte der deutsche Einzelhandel im engeren Sinne 2024 in den letzten beiden Monaten des Jahres -- ausgerechnet in dem Fenster, in dem eine Seite am wenigsten wackeln darf. Ein Lasttest beantwortet deshalb eine andere Frage als ein Tempo-Test. Nicht: Wie schnell ist eine einzelne Anfrage? Sondern: Wie viele Anfragen gleichzeitig verträgt das System, bevor Antwortzeiten und Fehlerrate kippen? Dieser Beitrag zeigt, wie sich ein realistisches Lastprofil aus Felddaten ableiten lässt, wie Testszenarien entlang echter Nutzerpfade entstehen, welche Kennzahlen unter Last wirklich zählen und wie sich eine Kapazitätsreserve so beziffern lässt, dass sie am Kampagnentag trägt. Wo dabei der Server der Engpass ist, setzt unsere Server-Optimierung an.
Das Wichtigste in Kürze
- 18,5 Prozent (HDE) des Umsatzes im Einzelhandel im engeren Sinne fielen 2024 auf November und Dezember; für das Weihnachtsgeschäft 2025 rechnete der Handelsverband mit 126,2 Milliarden Euro (HDE) Umsatz, davon 22,2 Milliarden Euro (HDE) online. Genau in diesem Fenster entscheidet die Kapazität, nicht die Bestmarke im Einzelabruf.
- Ein Einzelabruf misst Dauer, ein Lasttest misst Gleichzeitigkeit. Der Zusammenhang ist seit Langem beschrieben: Die Zahl der gleichzeitig im System befindlichen Anfragen entspricht dem Durchsatz multipliziert mit der Verweilzeit (Little 1961). Steigt die Verweilzeit, steigt die Gleichzeitigkeit -- und der Worker-Pool füllt sich.
- Die eigentlichen Zielgrößen sind Sättigungspunkt und Fehlerrate, nicht die Bestzeit. Der Sättigungspunkt liegt dort, wo der Durchsatz nicht mehr wächst, die Antwortzeit aber weiter steigt. Antwortzeiten gehören deshalb als Perzentile ausgewertet: Die Core Web Vitals werden im 75. Perzentil (web.dev) bewertet, unter Last lohnt zusätzlich der Blick auf p95 und p99.
- Testszenarien bilden echte Pfade ab: Kategorie mit Filtern, Suche, Warenkorb und Login. Diese Pfade unterscheiden sich stark in ihrer Cachebarkeit -- ein Test, der nur die gecachte Startseite abruft, misst das Auslieferungsnetz, aber kaum den Ursprungsserver.
- Vor der Saison gehören Cache-Aufwärmung, Notfallschalter für teure Funktionen und eine bezifferte Reserve zum Ergebnis. Wer rund 70 Prozent (Baymard Institute) Warenkorbabbrüche ohnehin gegen sich hat, sollte die Wartezeit nicht als weiteren Grund hinzufügen.
Warum 400 Millisekunden nichts über die Hochsaison sagen
Ein Tempo-Test misst eine Seite im Ruhezustand: eine Anfrage, ein Server, der sonst nichts zu tun hat, ein warmer Cache. Das Ergebnis ist ehrlich, aber es beschreibt einen Zustand, der am Kampagnentag kaum vorkommt. Unter Gleichzeitigkeit ändert sich die Physik der Sache. Jede Anfrage belegt für die Dauer ihrer Bearbeitung einen Platz: einen Prozess im Worker-Pool, eine Datenbankverbindung, ein Stück Arbeitsspeicher, Zeit auf einem CPU-Kern. Solange freie Plätze vorhanden sind, bleibt die Antwortzeit nahezu konstant. Ist der letzte Platz belegt, warten neue Anfragen in einer Schlange -- und ab diesem Moment addiert sich Wartezeit zur Bearbeitungszeit. Der Übergang ist nicht linear, sondern abrupt: Zwischen 'noch entspannt' und 'Zeitüberschreitung' liegen oft nur wenige Dutzend zusätzliche gleichzeitige Anfragen.
Wo genau der Platz ausgeht, ist von System zu System verschieden und selten dort, wo man es vermutet. Häufig ist es die Zahl der PHP-Prozesse, die gleichzeitig arbeiten dürfen; wie sich Laufzeit und Worker-Konfiguration aufeinander abstimmen lassen, behandelt der Beitrag zur PHP-Laufzeit mit OPcache, JIT und FPM-Workern. Ebenso häufig ist es die Datenbank: Eine Abfrage, die im Einzelabruf 40 Millisekunden braucht, kann unter Last auf ein Vielfaches gehen, weil Sperren, Sortierungen und Zwischentabellen sich gegenseitig ausbremsen -- das Vorgehen dazu steht im Beitrag zur Datenbank- und Query-Optimierung im Shop. Und manchmal ist es schlicht der Arbeitsspeicher, weil jeder zusätzliche Prozess seinen Anteil beansprucht und das System zu tauschen beginnt. Ein Lasttest sagt nicht nur, dass es klemmt, sondern wo.
Was Gleichzeitigkeit technisch bedeutet
Das Lastprofil aus Felddaten ableiten
Ein Lasttest ist nur so gut wie die Annahme, gegen die er testet. Eine runde Zahl aus dem Bauch -- '1.000 Nutzer sollten reichen' -- erzeugt entweder falsche Sicherheit oder unnötige Kosten. Die belastbare Grundlage sind Felddaten aus der vergangenen Saison: die stärkste Stunde, nicht der Tagesdurchschnitt, dazu die Verteilung der Einstiegsseiten und die Zahl der Seitenaufrufe je Sitzung. Wie sich Feldmessungen und aggregierte Berichte unterscheiden und wann welche Quelle taugt, ordnet der Beitrag zu Felddaten aus RUM und CrUX ein. Wichtig ist die Auflösung: Ein Stundenmittel glättet die Spitze weg, die beim Versand eines Newsletters oder beim Start einer Aktion in wenigen Minuten entsteht. Wer kann, schaut sich Minutenwerte an.
Zum Profil gehört ein zweiter Anteil, der gern vergessen wird: automatisierter Verkehr. Suchmaschinen-Crawler, Preisvergleicher und die neueren Inhalts-Crawler rufen Seiten ab, die kaum jemand sonst aufruft -- tiefe Filterkombinationen, Sortiervarianten, alte Detailseiten. Diese Anfragen laufen häufig am Cache vorbei und landen direkt auf dem Ursprungsserver; wie stark das ins Gewicht fällt, zeigt der Beitrag zur Crawler-Last auf dem Server. Für das Lastprofil heißt das: Der Bot-Anteil gehört als eigene Größe ausgewiesen und mitgetestet, sonst misst der Test eine freundlichere Welt als die reale. Ein realistisches Profil enthält am Ende drei Angaben: Anfragen pro Sekunde in der Spitze, die Mischung der Pfade und den erwarteten Zuwachs gegenüber der letzten Saison.
- Die stärkste Stunde der vergangenen Hochsaison aus den Felddaten holen -- und darin die stärksten fünf Minuten
- Sitzungen, Seitenaufrufe je Sitzung und die Verteilung über die Einstiegsseiten auslesen
- Den Anteil an Crawlern und automatisiertem Verkehr getrennt ausweisen, weil er den Ursprungsserver real belastet
- Den geplanten Zuwachs aus Werbebudget, Newsletter-Reichweite und Sortimentsausweitung als Faktor auflegen
- Daraus Anfragen pro Sekunde und die Zahl gleichzeitig in Bearbeitung befindlicher Anfragen berechnen
Testszenarien entlang echter Nutzerpfade
Ein Test, der nur die Startseite abruft, misst in den meisten Fällen das Auslieferungsnetz und nicht den Shop. Die Startseite ist gecacht, statisch und billig. Interessant wird es dort, wo Personalisierung, Filterlogik und Schreibvorgänge ins Spiel kommen. Ein brauchbares Szenario bildet deshalb den Weg nach, den Menschen tatsächlich gehen -- mit denselben Anteilen wie im Feld und mit realistischen Denkpausen zwischen den Schritten. Wer ohne Pausen testet, erzeugt eine Last, die es so nicht gibt, und verschiebt den gemessenen Sättigungspunkt nach unten. Vier Pfade tragen in einem Shop den Großteil der Last:
Kategorie und Filter
Der teuerste Pfad in vielen Shops. Jede zusätzliche Filterkombination erzeugt eine eigene Ergebnismenge, die sich schlecht cachen lässt. Im Test gehören Sortierung, Seitenblättern und mehrere Filter kombiniert -- nicht nur der Aufruf der ersten Seite ohne Auswahl.
Suche
Volltextsuche trifft Datenbank oder Suchindex direkt und liefert für jede Eingabe ein anderes Ergebnis. Im Szenario gehören echte Suchbegriffe aus den Protokollen der letzten Saison, inklusive Tippfehlern und Begriffen ohne Treffer, weil gerade diese teuer sind.
Warenkorb und Kasse
Hier wird geschrieben, hier greift keine Zwischenspeicherung, hier hängen Bestand, Versandkosten und Steuerlogik dran. Rund 70 Prozent (Baymard Institute) der Warenkörbe werden ohnehin abgebrochen; zusätzliche Wartezeit an dieser Stelle ist besonders teuer.
Login und Konto
Angemeldete Sitzungen umgehen den Seitencache weitgehend und erzeugen dauerhaft Sitzungsdaten. Dazu kommt, dass die Anmeldung selbst rechenintensiv ist. Wie stark der Ursprungsserver dabei antwortet, hängt an der Serverantwortzeit.
Die Mischung dieser Pfade entscheidet über die Aussagekraft des Tests. Liegt der Anteil gecachter Seitenaufrufe im Feld bei 70 Prozent, sollte er im Test nicht bei 95 Prozent liegen -- sonst misst man vor allem, wie gut das Auslieferungsnetz arbeitet. Umgekehrt erzeugt ein Test, der jeden Aufruf am Cache vorbeischickt, ein zu düsteres Bild. Wie sich Inhalte sinnvoll auf Kanten- und Ursprungsebene verteilen, behandelt der Beitrag zu CDN- und Edge-Caching im Shop; welche Schichten dabei zusammenspielen, fasst unsere Übersicht der Caching-Strategien zusammen. Für den Test gilt: Die Cache-Trefferquote gehört als eigene Kennzahl mitgemessen, sonst bleibt unklar, welche Schicht der Engpass war.
Sättigungspunkt und Fehlerrate als Zielgrößen
Die entscheidende Beobachtung im Lasttest ist nicht eine einzelne Zahl, sondern ein Kurvenverlauf. Man fährt die Gleichzeitigkeit in Stufen hoch und beobachtet zwei Größen zugleich: den Durchsatz in Anfragen pro Sekunde und die Antwortzeit im hohen Perzentil. Am Anfang steigen beide gemeinsam, der Durchsatz linear, die Antwortzeit kaum. Dann flacht der Durchsatz ab, während die Antwortzeit weiter klettert. Der Punkt, an dem beide Kurven auseinanderlaufen, ist der Sättigungspunkt: Mehr Last erzeugt ab hier keinen zusätzlichen Umsatz mehr, sondern nur noch längere Schlangen. Alles dahinter ist Überlast. Diesen Punkt zu kennen, ist wertvoller als jede Bestmarke, denn er lässt sich direkt mit dem Lastprofil aus den Felddaten vergleichen.
// Lastziel aus Felddaten ableiten (Zusammenhang nach Little 1961)
const sitzungenSpitzenstunde = 18000; // Sitzungen in der stärksten Stunde
const seitenProSitzung = 7; // Seitenaufrufe je Sitzung
const p95Serverzeit = 0.8; // Sekunden je Anfrage, 95. Perzentil
const reserveFaktor = 1.5; // Kapazitätsreserve
const anfragenProSekunde = (sitzungenSpitzenstunde * seitenProSitzung) / 3600;
const gleichzeitig = anfragenProSekunde * p95Serverzeit;
const zielGleichzeitig = Math.ceil(gleichzeitig * reserveFaktor);
console.log(anfragenProSekunde, gleichzeitig, zielGleichzeitig);
// 35 28 42 -> Testziel: 35 Anfragen/s dauerhaft, 42 gleichzeitig in ArbeitDie zweite Zielgröße ist die Fehlerrate, und sie wird regelmäßig unterschätzt. Ein System, das unter Last langsam wird, ist unangenehm; ein System, das Verbindungen abweist oder Zeitüberschreitungen liefert, verliert Bestellungen und verwirrt Suchmaschinen. Für den geordneten Rückfall gibt es Werkzeuge im Protokoll selbst: Der Statuscode 503 signalisiert eine vorübergehende Überlastung und kann mit einem Retry-After-Feld angeben, wann ein erneuter Versuch sinnvoll ist (RFC 9110); der Statuscode 429 weist ein Übermaß an Anfragen aus derselben Quelle ab und kennt dasselbe Feld (RFC 6585). Das ist deutlich besser als eine offene Verbindung, die irgendwann verfällt. Für die Sichtbarkeit ist das ebenfalls relevant: Antwortet ein Server dauerhaft langsam oder mit Serverfehlern, drosselt der Crawler seine Abrufrate (Google Search Central) -- die Auswirkungen einer Überlastung reichen also über den Kampagnentag hinaus. Wie stabil die Antwortzeit im Ausgangszustand ist, klärt vorab eine Messung der Serverantwortzeit.
| Aspekt | Einzelabruf (Tempo-Test) | Lastfenster (Lasttest) |
|---|---|---|
| Was gemessen wird | Dauer einer einzelnen Anfrage | Verhalten bei vielen Anfragen gleichzeitig |
| Leitkennzahl | Antwortzeit im Median | Durchsatz und Antwortzeit im 95. Perzentil |
| Fehler | fallen kaum an | Zeitüberschreitungen, 5xx, abgewiesene Verbindungen |
| Sichtbarer Engpass | Code, Abfragen, Übertragungsgrößen | Worker-Pool, Verbindungen, Arbeitsspeicher, CPU |
| Aussagekraft für die Hochsaison | begrenzt | hoch |
| Typische Fehldeutung | grün bedeutet tragfähig | Sättigung mit Ausfall verwechseln |
Antwortzeit-Perzentile unter Last lesen
Ein Mittelwert ist unter Last die unbrauchbarste aller Kennzahlen. Wenn neun von zehn Anfragen in 200 Millisekunden beantwortet werden und die zehnte acht Sekunden braucht, liegt der Durchschnitt bei knapp einer Sekunde -- eine Zahl, die keinen einzigen realen Besuch beschreibt. Perzentile beschreiben dagegen Erfahrung: Der Wert im 95. Perzentil sagt, wie langsam es für die langsamsten fünf Prozent der Anfragen wurde. Genau diese fünf Prozent sind in der Hochsaison oft die Menschen im Warenkorb, weil dort weder Seitencache noch Auslieferungsnetz helfen. Nicht zufällig bewertet auch Google die Core Web Vitals im 75. Perzentil (web.dev) statt im Mittel; die Einordnung der drei Kennzahlen liefert unsere Seite zu den Core Web Vitals. Für einen Lasttest empfiehlt sich zusätzlich p99, weil dort die Warteschlangen zuerst sichtbar werden.
Für die Bewertung braucht es Schwellen, die vorher feststehen. Als Anhaltspunkt dienen die Schwellen aus dem Feld: 2,5 Sekunden (web.dev) für einen guten LCP, 800 Millisekunden (web.dev) für eine gute Serverantwortzeit und 200 Millisekunden (web.dev) für eine gute Reaktionszeit auf Eingaben. Ein Lasttest übersetzt diese Schwellen in eine Kapazitätsaussage und legt sie dabei bewusst strenger an als die Feldbewertung im 75. Perzentil: Bis zu welcher Gleichzeitigkeit bleibt die Serverantwortzeit im 95. Perzentil unter 800 Millisekunden? Diese Formulierung ist prüfbar, sie lässt sich wiederholen, und sie taugt als Abnahmekriterium vor der Saison. Der Rest des Bildes bleibt derselbe: Ein schlanker Seitenaufbau hilft auch unter Last, denn die mittlere mobile Startseite wog im Juli 2025 2.362 KB (Web Almanac 2025) -- jede eingesparte Anfrage ist eine, die keinen Platz im Worker-Pool belegt.
Der Kern in einem Satz
Cache-Aufwärmung und Notfallschalter
Zwei Dinge entscheiden am Kampagnentag oft mehr als die reine Rechenleistung. Das erste ist der Zustand des Caches beim Start. Nach einer Veröffentlichung, einem Neustart oder einer Sortimentsänderung ist der Zwischenspeicher leer, und die ersten Tausend Besucher treffen einen Server, der jede Seite neu bauen muss. Genau in diesem Moment eine Werbekampagne zu starten, ist die häufigste vermeidbare Ursache für einen Ausfall. Die Gegenmaßnahme ist unspektakulär: Die wichtigsten Kategorien, Landingseiten und Suchbegriffe werden vor dem Start planmäßig abgerufen, damit die Zwischenspeicher gefüllt sind. Welche Schichten dabei zusammenwirken und wo sie sich gegenseitig aushebeln, beschreibt der Beitrag zu Caching-Strategien mit Varnish und Redis. Im Lasttest lässt sich beides messen: einmal mit kaltem, einmal mit warmem Cache. Der Unterschied ist regelmäßig größer als erwartet.
Das zweite ist ein vorbereiteter Rückfall. Nicht jede Funktion eines Shops ist am Spitzentag gleich wichtig. Persönliche Empfehlungen, Live-Bestandsanzeigen je Variante oder aufwendige Auswertungen im Frontend kosten Rechenzeit, tragen aber wenig zur Kaufentscheidung bei. Ein Notfallschalter macht diese Funktionen abschaltbar, ohne dass jemand Code anfassen oder eine Veröffentlichung ausrollen muss -- als Konfiguration, die eine Person unter Druck in einer Minute umlegen kann. Damit das im Ernstfall funktioniert, gehört der Schalter in den Lasttest: einmal mit allen Funktionen, einmal im reduzierten Betrieb. Erst dann ist bekannt, wie viel Kapazität er tatsächlich freigibt.
- Live-Suche mit teurer Volltextabfrage auf eine schlankere Variante umschalten
- Persönliche Empfehlungen und zuletzt angesehene Artikel vorübergehend ausblenden
- Bestandsanzeige je Variante auf eine zwischengespeicherte Sammelangabe reduzieren
- Filterkombinationen mit sehr geringer Trefferzahl aus der Navigation nehmen
- Nicht kaufrelevante Auswertungsskripte im Frontend anhalten
- Gültigkeitsdauern im Seitencache verlängern und geplante Neuaufbauten verschieben
Woran ein Lasttest scheitert
Die Kapazitätsreserve beziffern und halten
Am Ende eines Lasttests sollte ein Satz stehen, den auch die Geschäftsführung versteht: Das System trägt bei der vereinbarten Antwortzeitschwelle X gleichzeitige Anfragen, erwartet werden Y, die Reserve beträgt also das Z-fache. Ein Faktor von 1,5 gegenüber der erwarteten Spitze ist ein üblicher Ausgangspunkt, für Kampagnen mit unsicherer Reichweite eher das Doppelte. Diese Reserve ist keine Verschwendung, sondern der Puffer für das, was sich nicht planen lässt: ein Newsletter, der besser läuft als gedacht, ein Beitrag, der geteilt wird, eine Crawler-Welle zur Unzeit. Ob die Reserve über mehr Ressourcen, bessere Ausnutzung oder eine andere Betriebsform entsteht, ist eine Abwägung von Kosten und Aufwand; die Unterschiede der Betriebsformen ordnet der Beitrag zur Hosting-Wahl und Serverantwortzeit ein.
Der wirtschaftliche Rahmen macht die Rechnung greifbar: Der deutsche Onlinehandel setzte 2025 83,1 Milliarden Euro (bevh) mit Waren um, ein Plus von 3,2 Prozent (bevh) gegenüber dem Vorjahr. Ein Ausfall von zwei Stunden am Spitzentag kostet in dieser Größenordnung mehr als die Kapazität, die ihn verhindert hätte -- und er kostet zusätzlich Vertrauen, denn 53 Prozent (Google) der mobilen Besuche werden abgebrochen, wenn eine Seite länger als drei Sekunden lädt. Eine Kapazitätsaussage ist damit keine technische Fußnote, sondern eine Planungsgröße neben Werbebudget und Warenbestand.
- Lastprofil aus den Felddaten der vergangenen Hochsaison ableiten und mit der aktuellen Planung abgleichen
- Szenarien entlang der vier Hauptpfade schreiben, mit realistischer Pfadmischung und Denkpausen
- In Stufen hochfahren, bis Durchsatz und Antwortzeit auseinanderlaufen -- das ist der Sättigungspunkt
- Den Engpass benennen, beheben und erneut messen: Worker, Verbindungen, Abfragen, Zwischenspeicher
- Reservefaktor festlegen, Cache-Aufwärmung und Notfallschalter dokumentieren, Kennzahlen laufend überwachen
Genau so ist ein Vor-Saison-Projekt bei uns zugeschnitten: Wir leiten das Lastprofil aus Ihren Felddaten ab, bauen Szenarien entlang der echten Pfade, fahren die Last in Stufen hoch und benennen den Punkt, an dem Durchsatz und Antwortzeit auseinanderlaufen. Danach folgt die Arbeit am Engpass -- Serverkonfiguration, Zwischenspeicherung, Datenbank -- und eine zweite Messung, die den Fortschritt belegt. Für Shopware-Projekte verbinden wir das mit den übrigen Hebeln der Shopware-Performance; welche Bausteine insgesamt dazugehören, zeigt die Übersicht unserer Performance-Leistungen. Nach der Saison bleibt die Überwachung, damit die Reserve nachweisbar bleibt und nicht unbemerkt aufgezehrt wird.
Kapazität ist kein Zustand, sondern ein Messwert mit Verfallsdatum. Jede neue Funktion, jedes zusätzliche Skript und jede gewachsene Datenmenge verschiebt den Sättigungspunkt ein Stück nach unten. Wer ihn einmal im Jahr misst, weiß im Dezember, woran er ist.
Zwei Ergänzungen runden das Bild ab. Erstens verschiebt sich Kapazität nicht nur auf dem Server: Lange Sitzungen im Browser können über Stunden Speicher ansammeln und die Seite träge machen, ohne dass der Server etwas davon merkt -- das Thema behandelt der Beitrag zu Speicherlecks im Frontend bei langen Sitzungen. Zweitens ersetzt ein Lasttest keine laufende Kontrolle im Bauprozess: Ob eine Veröffentlichung das Seitengewicht oder die Ausführungszeit verschlechtert hat, gehört automatisiert geprüft, wie im Beitrag zum Performance-Budget in der Baukette beschrieben. Der Lasttest beantwortet die Frage nach der Gleichzeitigkeit, das Budget die Frage nach der schleichenden Verschlechterung -- beide zusammen halten die Reserve stabil. Wo ein Shop heute steht, klärt am schnellsten eine Performance-Analyse mit Blick auf Server, Zwischenspeicherung und Frontend.
Quellen und Studien