PHP-FPM Pools, CPU-Limits und Autoscaling messbar ableiten
Wer CPU- und Speicherlimits für Magento-Container nach Bauchgefühl setzt, überprovisioniert entweder teuer oder riskiert Ausfälle bei Lastspitzen. Dieser Artikel zeigt, wie Magento Container Größen systematisch aus PHP-FPM Pool-Sizing, realem Speicherbedarf pro Worker und tatsächlichen Traffic-Mustern abgeleitet und per Lasttest validiert werden.
Inhaltsverzeichnis
- 1. Warum pauschale CPU- und RAM-Limits scheitern
- 2. PHP-FPM Pool-Größe aus Traffic ableiten
- 3. Speicherbedarf pro Worker realistisch messen
- 4. CPU-Limits und Request-Latenz unter Last
- 5. Traffic-Muster: Baseline, Peak und Sale-Events
- 6. Horizontal vs. vertikal skalieren
- 7. Autoscaling-Regeln für Magento-Container definieren
- 8. Lasttests zur Validierung der Dimensionierung
- 9. Shop-Größen und empfohlene Container-Größen im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum pauschale CPU- und RAM-Limits scheitern
Ein häufiges Muster bei der Konfiguration von Magento-Containern ist, CPU- und Speicherlimits nach einer pauschalen Regel wie „2 CPUs, 2 Gigabyte RAM pro Container“ zu setzen, ohne den tatsächlichen Traffic des Shops zu berücksichtigen. Diese Magento Container Größen passen zufällig für manche Shops, sind für andere massiv überdimensioniert und für wieder andere während Lastspitzen zu knapp bemessen. Das Ergebnis sind entweder unnötig hohe Infrastrukturkosten oder Performance-Einbrüche genau dann, wenn der Shop am meisten Umsatz macht.
Die richtige Methode, Magento Container Größen nach Traffic zu dimensionieren, beginnt nicht mit einer Ressourcenzahl, sondern mit einer Frage: Wie viele gleichzeitige Requests muss ein Container bedienen können, und wie viel Speicher und CPU verbraucht ein einzelner PHP-FPM-Worker unter realer Last. Aus diesen beiden Werten lässt sich die Container-Größe rückwärts berechnen, statt sie zu raten.
Dieser Artikel geht Schritt für Schritt durch die Messgrößen, die für eine fundierte Container-Dimensionierung nach Traffic bei Magento nötig sind, von PHP-FPM Pool-Sizing über CPU-Limits bis zu Autoscaling-Regeln und Lasttests zur Validierung.
2. PHP-FPM Pool-Größe aus Traffic ableiten
Die PHP-FPM Pool-Größe, also die Anzahl der Worker-Prozesse pro Container, ist der zentrale Hebel für die Magento Container Größe. Jeder Worker kann genau einen Request gleichzeitig bearbeiten, weshalb die Pool-Größe direkt die maximale Anzahl paralleler Requests pro Container bestimmt. Die Formel dafür ist einfach: Gewünschte gleichzeitige Requests geteilt durch die Anzahl der Container ergibt die nötige Pool-Größe pro Container.
Der kritische Eingabewert für diese Formel ist die durchschnittliche Request-Dauer unter Last, nicht die Antwortzeit bei niedriger Last. Ein Magento-Request, der bei wenig Traffic 200 Millisekunden dauert, kann unter hoher Last durch Datenbank-Lock-Contention oder CPU-Sättigung auf 800 Millisekunden ansteigen, was die effektiv verfügbare Kapazität pro Worker um den Faktor vier reduziert. Die Pool-Größe muss deshalb anhand der Request-Dauer unter realistischer Spitzenlast kalkuliert werden, nicht anhand von Idealwerten.
#!/usr/bin/env bash
# calculate-pool-size.sh — derive PHP-FPM pool size from target concurrency
set -euo pipefail
TARGET_CONCURRENT_REQUESTS=200
AVG_REQUEST_DURATION_MS=400
TARGET_THROUGHPUT_PER_SEC=$(( TARGET_CONCURRENT_REQUESTS * 1000 / AVG_REQUEST_DURATION_MS ))
echo "[INFO] Target throughput: ${TARGET_THROUGHPUT_PER_SEC} requests/sec"
echo "[INFO] Required pool size for ${TARGET_CONCURRENT_REQUESTS} concurrent requests: ${TARGET_CONCURRENT_REQUESTS}"
echo "[INFO] With 4 containers, pool size per container: $(( TARGET_CONCURRENT_REQUESTS / 4 ))"
3. Speicherbedarf pro Worker realistisch messen
Der Arbeitsspeicher pro PHP-FPM-Worker ist keine feste Konstante, sondern hängt stark davon ab, welche Magento-Seite verarbeitet wird. Ein einfacher API-Request verbraucht deutlich weniger Speicher als ein komplexer Checkout-Request mit vielen geladenen Modulen und Plugins. Für eine realistische Container-Dimensionierung muss der Speicherbedarf unter dem worst case gemessen werden, also bei den speicherintensivsten Requests, die der Shop tatsächlich bedient, nicht beim Durchschnitt.
Die Messung erfolgt am zuverlässigsten über docker stats während eines gezielten Lasttests, kombiniert mit PHP-eigenen Metriken wie memory_get_peak_usage() pro Request. Ein realistischer Wert für einen produktiven Magento-Container liegt zwischen 40 und 120 Megabyte pro Worker, abhängig von Anzahl und Komplexität installierter Module. Die Container-Speichergrenze muss mindestens das Produkt aus Pool-Größe und Peak-Speicherbedarf pro Worker sein, zuzüglich eines Puffers von 20 bis 30 Prozent für PHP-eigene Overhead-Prozesse wie OPcache.
# docker-compose.yml — memory limit derived from pool size and per-worker peak usage
services:
magento-web:
image: registry.mironsoft.de/magento-shop:latest
environment:
PHP_FPM_PM_MAX_CHILDREN: "50"
deploy:
resources:
limits:
# 50 workers * 100MB peak + 25% buffer for OPcache and shared extensions
memory: 6250M
cpus: "4.0"
reservations:
memory: 4000M
cpus: "2.0"
4. CPU-Limits und Request-Latenz unter Last
Ein zu knapp bemessenes CPU-Limit für einen Magento-Container führt zu einem subtilen, aber gefährlichen Effekt: PHP-FPM-Worker werden vom Container-Runtime gedrosselt, sobald das CPU-Kontingent innerhalb eines Zeitfensters aufgebraucht ist, was zu Latenz-Spitzen führt, ohne dass die CPU-Auslastung im Monitoring auf den ersten Blick als kritisch erscheint. Dieses sogenannte CPU-Throttling ist bei Kubernetes und Docker mit CFS-Quota-basierten Limits gut dokumentiert, wird aber bei der Container-Dimensionierung häufig übersehen.
Als Faustregel für Magento Container Größen gilt: Mindestens ein CPU-Kern pro acht bis zwölf gleichzeitig aktive PHP-FPM-Worker, abhängig davon, wie CPU-intensiv die durchschnittlichen Requests des jeweiligen Shops sind. Shops mit komplexen Preisregeln, vielen Konfigurationsprodukten oder aufwändigen Custom-Modulen brauchen tendenziell mehr CPU pro Worker als ein Standard-Katalog mit einfachen Produkten.
5. Traffic-Muster: Baseline, Peak und Sale-Events
Die Container-Größe für die alltägliche Baseline-Last unterscheidet sich fundamental von der Größe, die während eines Sale-Events wie Black Friday gebraucht wird. Wer Magento Container Größen nach Traffic dimensioniert, sollte diese drei Lastprofile getrennt betrachten: die Baseline für einen normalen Werktag, die tägliche Peak-Last zu Stoßzeiten am Abend, und die außergewöhnliche Sale-Last, die ein Vielfaches der normalen Peak-Last erreichen kann.
Eine feste Container-Größe für alle drei Szenarien ist wirtschaftlich ineffizient, weil sie entweder für die Baseline überdimensioniert oder für Sale-Events unterdimensioniert ist. Die praktikable Lösung ist eine Kombination aus konservativ dimensionierten Baseline-Containern und einer Autoscaling-Regel, die bei erkanntem Peak- oder Sale-Traffic automatisch zusätzliche Container-Replikas startet, statt jederzeit die maximale Kapazität vorzuhalten.
6. Horizontal vs. vertikal skalieren
Vertikales Skalieren, also größere CPU- und Speicherlimits für denselben Container, hat bei Magento einen klaren Nachteil: Es erhöht die Kapazität eines einzelnen PHP-FPM-Pools, erhöht aber auch das Risiko, dass ein einzelner fehlerhafter Deployment- oder Memory-Leak-Vorfall den gesamten vertikal skalierten Container und damit einen größeren Anteil der Gesamtkapazität betrifft. Horizontales Skalieren, also mehr Container-Replikas mit moderater Einzelgröße, verteilt dieses Risiko und erlaubt zusätzlich granularere Anpassung an schwankenden Traffic.
Für die meisten Magento-Shops ist horizontales Skalieren die bessere Standardstrategie für die Web-Container, weil sie zustandslos sind und beliebig repliziert werden können. Vertikales Skalieren bleibt sinnvoll für Dienste, die naturgemäß nicht horizontal skalieren, etwa MySQL als primäre Schreibinstanz oder den dedizierten Cron-Container, der wie in einem separaten Artikel beschrieben ohnehin nur eine Instanz haben darf.
7. Autoscaling-Regeln für Magento-Container definieren
Autoscaling-Regeln für Magento Container sollten sich primär an der PHP-FPM-Worker-Auslastung orientieren, nicht ausschließlich an der rohen CPU-Auslastung. Ein Container mit hoher CPU-Auslastung, aber noch freien PHP-FPM-Workern hat noch Kapazitätsreserven, während ein Container mit allen Workern in Benutzung, aber moderater CPU-Auslastung bereits am Limit der Nebenläufigkeit arbeitet und neue Replikas braucht.
Die Metrik listen queue aus dem PHP-FPM-Status-Endpunkt ist dafür der zuverlässigste Indikator: Sobald Requests in dieser Warteschlange landen, weil alle Worker beschäftigt sind, ist der Container faktisch am Limit, unabhängig vom CPU-Prozentwert. Eine Autoscaling-Regel, die bei einer listen queue größer null für mehr als 30 Sekunden eine zusätzliche Replika startet, reagiert deutlich präziser auf echten Kapazitätsdruck als eine reine CPU-Schwellenwert-Regel.
# autoscale-rule.yml — scale based on PHP-FPM listen queue, not raw CPU
rules:
- metric: php_fpm_listen_queue
condition: "> 0"
duration: 30s
action: scale_up
increment: 1
max_replicas: 12
- metric: php_fpm_listen_queue
condition: "== 0"
duration: 300s
action: scale_down
decrement: 1
min_replicas: 3
- metric: cpu_throttled_periods
condition: "> 5%"
duration: 60s
action: alert
message: "CPU limit too tight, workers being throttled"
8. Lasttests zur Validierung der Dimensionierung
Jede berechnete Magento Container Größe ist eine Hypothese, bis sie unter realistischer Last validiert wurde. Ein Lasttest mit einem Tool wie k6 oder Apache Bench, das den tatsächlichen User-Flow simuliert, von Kategorieseite über Produktseite bis Checkout, deckt auf, ob die berechnete Pool-Größe und die gesetzten Ressourcenlimits der Realität standhalten oder ob theoretische Annahmen falsch waren.
Wichtig ist, den Lasttest gegen eine Umgebung zu fahren, die der Produktion in Ressourcenlimits, Datenmenge und Netzwerktopologie möglichst nahekommt. Ein Lasttest gegen einen lokalen Entwicklungscontainer ohne gesetzte Limits liefert falsche Sicherheit, weil er die Effekte von CPU-Throttling und Speichergrenzen, die in Produktion tatsächlich greifen, gar nicht erst zeigt.
# k6-loadtest.js — simulate realistic Magento traffic to validate container sizing
import http from "k6/http";
import { sleep, check } from "k6";
export const options = {
stages: [
{ duration: "2m", target: 50 }, // ramp up to baseline
{ duration: "5m", target: 200 }, // sustained peak load
{ duration: "2m", target: 400 }, // sale-event spike
{ duration: "2m", target: 0 }, // ramp down
],
};
export default function () {
const category = http.get("https://staging.shop.test/catalog/category/view/id/5");
check(category, { "category status 200": (r) => r.status === 200 });
const product = http.get("https://staging.shop.test/catalog/product/view/id/1234");
check(product, { "product status 200": (r) => r.status === 200 });
sleep(1);
}
9. Shop-Größen und empfohlene Container-Größen im Vergleich
Als grober Orientierungspunkt hilft eine Übersicht typischer Magento Container Größen nach Shop-Kategorie, wohlgemerkt als Startpunkt für eigene Messungen, nicht als Ersatz für Lasttests.
| Shop-Größe | Baseline Container | Pool-Größe pro Container | Peak-Replikas |
|---|---|---|---|
| Klein (unter 1.000 Bestellungen/Monat) | 2 CPU, 2 GB RAM | 15 bis 20 Worker | 2 bis 3 Replikas |
| Mittel (1.000 bis 10.000 Bestellungen/Monat) | 4 CPU, 4 GB RAM | 30 bis 50 Worker | 4 bis 6 Replikas |
| Groß (über 10.000 Bestellungen/Monat) | 8 CPU, 8 GB RAM | 60 bis 100 Worker | 8 bis 15 Replikas |
| Sale-Event (jede Größe) | Baseline plus Autoscaling | Unverändert pro Container | 2 bis 4x der Peak-Replikas |
Diese Tabelle ersetzt keine eigenen Messungen, weil Modulanzahl, Produktkomplexität und Custom-Code die tatsächlichen Werte pro Shop deutlich verschieben können. Sie eignet sich aber als Ausgangspunkt, um mit realistischen Startwerten in die eigene Container-Dimensionierung nach Traffic zu gehen, statt bei null anzufangen.
Mironsoft
Ressourcen-Dimensionierung für Magento-Infrastruktur
Container-Größen, die zu eurem echten Traffic passen?
Wir messen PHP-FPM Pool-Auslastung und Speicherbedarf pro Worker in eurem Shop, leiten daraus passende Ressourcenlimits ab und richten Autoscaling-Regeln ein, die auf echten Kapazitätsdruck reagieren statt auf CPU-Prozentwerte.
Traffic-Analyse
Baseline, Peak und Sale-Muster aus echten Zugriffsdaten ableiten
Lasttest-Setup
Realistische k6-Lasttests gegen eine produktionsnahe Staging-Umgebung aufbauen
Autoscaling
Skalierungsregeln auf Basis der PHP-FPM Listen Queue statt CPU-Schwellenwerten einrichten
10. Zusammenfassung
Magento Container Größen nach Traffic zu dimensionieren beginnt mit zwei Messgrößen: der Request-Dauer unter realistischer Last, aus der sich die nötige PHP-FPM Pool-Größe ableitet, und dem Peak-Speicherbedarf pro Worker, aus dem sich die Speichergrenze des Containers ergibt. CPU-Limits müssen großzügig genug bemessen sein, um CPU-Throttling zu vermeiden, das sonst zu Latenz-Spitzen führt, die im CPU-Prozent-Monitoring unsichtbar bleiben.
Horizontales Skalieren ist für die zustandslosen Web-Container die robustere Standardstrategie gegenüber vertikalem Skalieren, weil es Risiko verteilt und granularer auf Lastschwankungen reagiert. Autoscaling-Regeln, die sich an der PHP-FPM Listen Queue statt an roher CPU-Auslastung orientieren, treffen die tatsächliche Kapazitätsgrenze deutlich präziser. Lasttests mit realistischen Traffic-Mustern sind der letzte, unverzichtbare Schritt, um eine berechnete Dimensionierung vor dem produktiven Einsatz zu validieren.
Magento Container Größen nach Traffic dimensionieren — Das Wichtigste auf einen Blick
Pool-Größe
Aus Ziel-Nebenläufigkeit und Request-Dauer unter realer Last berechnen, nicht raten.
Speicherlimit
Pool-Größe mal Peak-Speicherbedarf pro Worker plus 20 bis 30 Prozent Puffer.
CPU-Limits
Mindestens ein Kern pro acht bis zwölf gleichzeitige Worker, gegen CPU-Throttling.
Autoscaling
PHP-FPM Listen Queue als Skalierungssignal, präziser als CPU-Prozentwerte.