...

PHP Handler Vergleich: Auswirkungen auf Webhosting Performance

Dieser PHP Handler Vergleich zeigt, wie mod_php, CGI, FastCGI, PHP-FPM und LSAPI die Performance deines Hostings beeinflussen – von CPU-Last bis Tail-Latenzen. Ich erkläre konkret, welche Wahl bei WordPress, WooCommerce und Traffic-Spitzen die Ladezeit senkt und gleichzeitig Ressourcen schont.

Zentrale Punkte

  • PHP-FPM skaliert effizienter als mod_php und FastCGI.
  • LSAPI liefert die besten Werte auf LiteSpeed.
  • Isolation pro Benutzer erhöht Sicherheit.
  • OPcache und Redis reduzieren Latenzen.
  • P95/P99 zeigt echte Nutzererfahrung.

Wie PHP-Handler arbeiten

Ein PHP-Handler verbindet den Webserver mit dem Interpreter und steuert Prozesse, Speicher und I/O für jede Anfrage. CGI startet für jeden Request einen frischen Prozess und lädt Konfigurationen neu, was Overhead erzeugt und die Latenz erhöht. Moderne Varianten wie FastCGI, PHP-FPM oder LSAPI halten Worker persistent bereit und sparen dadurch Startzeit, Kontextwechsel und CPU-Zyklen. OPcache bleibt im Speicher, wodurch Bytecode nicht jedes Mal kompilieren muss und dynamische Seiten schneller antworten. Gleichzeitig entscheidet das Prozess-Management darüber, wie viele gleichzeitige Requests laufen dürfen, wie Prioritäten gesetzt werden und wie sich Lastspitzen abfedern lassen.

Direktvergleich der gängigen Handler

Die Wahl des Handlers bestimmt die Skalierung, das Sicherheitsmodell und den RAM-Bedarf einer Anwendung. mod_php bindet PHP in den Apache-Prozess ein und liefert kurze Antwortzeiten, leidet jedoch an schwacher Isolation zwischen Konten. CGI trennt Benutzer sauber, kostet aber massiv CPU-Zeit pro Request. FastCGI reduziert den Overhead, bleibt jedoch weniger effizient als ein gut getuntes PHP-FPM. LSAPI setzt noch einen drauf, wenn LiteSpeed im Einsatz ist, und stabilisiert besonders die Tail-Latenzen bei vielen gleichzeitigen Verbindungen.

Handler Performance Sicherheit RAM-Bedarf Skalierbarkeit Einsatzszenario
mod_php Hoch Niedrig Niedrig Mittel Kleine Sites, seltene Peaks
CGI Niedrig Hoch Hoch Niedrig Statische Inhalte, Tests
FastCGI Mittel Mittel Mittel Mittel Übergangslösung
PHP-FPM Sehr hoch Hoch Niedrig Hoch Shared Hosting, CMS
LSAPI Höchste Mittel Sehr niedrig Sehr hoch High-Traffic, E‑Commerce

PHP-FPM im Praxis-Check: Prozesse, Pools, Tuning

PHP-FPM arbeitet mit Worker-Pools, die Anfragen aus einer Warteschlange ziehen und dadurch Lastspitzen elegant abfedern. Ich setze pro Website einen eigenen Pool, sodass Konfiguration, Limits und User-Kontext getrennt bleiben und die Sicherheit steigt. In der Praxis rechnen sich adaptive Einstellungen wie pm = dynamic oder ondemand, weil sich die Anzahl aktiver Prozesse an die Nachfrage anpasst. Entscheidend ist die richtige Dimensionierung von pm.max_children und den Zeitlimits, damit die Queue nicht wächst und dennoch RAM-Reserven bleiben. Für den Einstieg empfehle ich die Parameter strukturiert zu prüfen; Details zum Feintuning erkläre ich hier: PHP-FPM Prozess-Management.

LSAPI und LiteSpeed: Spitzenwert bei hoher Gleichzeitigkeit

LSAPI hält PHP-Prozesse im Speicher und reduziert Kontextwechsel, wodurch dynamische Inhalte mit HTTP/3 und QUIC noch geschmeidiger geliefert werden. Unter Volllast bleibt die P95/P99-Latenz stabiler als bei vielen Alternativen, was die Nutzererfahrung sichtbar verbessert. Ich sehe bei Shop- und Content-Seiten regelmäßig mehr Anfragen pro Sekunde und kürzere TTFB, besonders wenn OPcache und Server-Cache zusammenarbeiten. Der Vorteil zeigt sich nicht allein in Durchschnittswerten, sondern bei gleichzeitigen Sessions, Sessions mit Cache-Misses und „kalten“ PHP-Workern. Wer den Architektur-Unterschied verstehen will, liest den Überblick zu LiteSpeed vs. Nginx und entscheidet danach über den Stack.

WordPress und WooCommerce: Messwerte richtig einordnen

Bei WordPress erziele ich mit PHP 8.2 auf FPM oder LSAPI hohe req/s-Werte, während WooCommerce durch Sessions, Cart-Logik und mehr Datenbankzugriffe etwas weniger Requests pro Sekunde schafft. Aussagekräftig wird der Test erst unter realistischem Traffic mit Caching-Hits und -Misses gemischt. Critical CSS, Objekt-Cache und persistente Verbindungen verschieben die Grenze, ab der Engpässe entstehen. Besonders hilfreich sind kurze TTLs für häufig veränderte Inhalte und differenzierte Cache-Keys für Sprache, Nutzerstatus und Gerätetyp. So bleibt die Seite schnell, obwohl sie personalisierte Inhalte ausliefert.

Sicherheit und Isolation: Pools, User-Kontext, Limits

Ich bevorzuge für Multi-User-Hosting getrennte Pools pro Konto, damit Rechte, Pfade und Limits sauber voneinander getrennt bleiben. mod_php teilt einen gemeinsamen Kontext, was das Risiko erhöht, wenn ein Projekt Lücken aufweist. FPM oder LSAPI mit per-User-Konfigurationen reduzieren diese Angriffsfläche deutlich, weil Prozesse unter dem jeweiligen Benutzer laufen. Hinzu kommt die Möglichkeit, unterschiedliche php.ini-Optionen auf Projektebene zu setzen, ohne andere Sites zu beeinflussen. Resource-Limits wie max_execution_time und memory_limit pro Pool verhindern, dass Ausreißer den Server ausbremsen.

Ressourcenverbrauch und RAM-Planung

Jeder PHP-Worker belegt je nach Code, Erweiterungen und OPcache-Größe deutlich variierenden Speicher, weshalb ich die tatsächliche Belegung messe statt zu raten. Tools wie ps, top oder systemd-cgtop zeigen, wie viel RAM aktive Worker wirklich belegen und wann Swapping droht. Danach lege ich pm.max_children konservativ fest, lasse Headroom für Datenbank, Webserver und Cache-Dienste und beobachte die P95-Latenz unter Peak. Bleiben Reserven, erhöhe ich die Child-Zahl schrittweise und prüfe wieder. So wächst die Gesamtkapazität kontrolliert, ohne den Server zu überziehen.

Messmethodik: Von TTFB bis P99

Ich bewerte nicht nur Durchschnittswerte, sondern vor allem P95– und P99-Latenzen, weil sie das echte Erlebnis unter Last abbilden. Ein Stack kann mit identischem Durchsatz arbeiten und trotzdem bei P99 schlechter wirken, wenn Warteschlangen wachsen. Deshalb teste ich kalte und warme Caches, mische Lese- und Schreibanfragen und verwende realistische Concurrency-Werte. Ohne OPcache-Warmup interpretiere ich Ergebnisse vorsichtig, da viele Systeme nach wenigen Warmup-Aufrufen deutlich schneller werden. Erst mit repräsentativen Testläufen entscheide ich über Handler, Caching-Strategie und Prozesslimits.

Entscheidungsleitfaden für die Wahl des Handlers

Für kleine Seiten mit wenigen Logins reicht mod_php oder ein sparsames FPM-Setup, sofern Sicherheitsaspekte adressiert werden. Wächst die Gleichzeitigkeit, wechsele ich zu PHP-FPM mit getrennten Pools pro Projekt und aktiviere OPcache konsequent. Bei stark dynamischen Shops und vielen Sessions bevorzuge ich LiteSpeed mit LSAPI, um P95 und P99 niedrig zu halten. Wer aus pricing- oder Architekturgründen bei Apache/Nginx bleibt, fährt mit sauber getuntem FPM sehr gut. In allen Fällen zählt die Messung unter realistischen Bedingungen mehr als Benchmarks auf leerem System.

Praxis-Setup: Caching, Sessions, Zeitlimits

Ich setze auf OPcache mit großzügiger Speicher-Allokation, damit Bytecode selten verdrängt wird, und verlagere Sessions nach Möglichkeit in Redis, um Datei-Locks zu vermeiden. Dadurch sinken Wartezeiten bei gleichzeitigen Logins und personalisierten Seiten. Für externe Dienste definiere ich klare Timeouts und Circuit-Breaker, damit Ausfälle nicht den gesamten Request blockieren. Auf Anwendungsebene halte ich Cache-TTLs kurz genug, um Aktualität zu wahren, aber lang genug für einen hohen Hit-Ratio. Wer regelmäßig gegen Worker-Limits rennt, findet hier einen Einstieg: PHP-Worker richtig balancieren.

Kosten-Nutzen-Abgleich und Betrieb

Ich bewerte die Kosten eines Wechsels gegen den messbaren Gewinn bei Latenz, Durchsatz und Ausfallsicherheit. Der Sprung von FastCGI auf PHP-FPM bringt oft mehr als ein Wechsel der PHP-Nebenversionsnummer, weil Prozess-Management und Caching kontinuierlich wirken. LSAPI lohnt sich vor allem dann, wenn LiteSpeed ohnehin im Einsatz ist und viele gleichzeitige Besucher anstehen. Wer den Stack umstellt, sollte Logs und Metriken eng begleiten und Rollback-Pfade vorbereiten. Ein geplanter A/B-Betrieb über mehrere Tage liefert die zuverlässigsten Aussagen.

Webserver-Zusammenspiel: Apache-MPM, Nginx und Keep-Alive

In der Praxis entscheidet nicht nur der PHP-Handler, sondern auch der Webserver-Modus. mod_php funktioniert mit Apache im prefork-MPM, blockiert aber die Nutzung moderner Event-Modelle. Wer HTTP/2, längere Keep-Alive-Phasen und Tausende Verbindungen effizient bedienen will, setzt auf Apache event + PHP-FPM oder auf Nginx/LiteSpeed als Frontend. Die Konsequenz: Die Anzahl benötigter PHP-Worker richtet sich nicht nach der Anzahl der TCP-Verbindungen, sondern nach den tatsächlich gleichzeitig laufenden PHP-Requests. HTTP/2/3-Multiplexing reduziert also Kopfzeilen-Overhead am Webserver, ändert aber nichts an zu knapp dimensionierten PHP-Pools.

Nginx leitet Anfragen typischerweise via FastCGI an FPM weiter. Ich achte auf kurze read_timeout– und send_timeout-Werte am Proxy, sonst entstehen 502/504-Fehler bei hängenden Upstreams, obwohl PHP noch arbeitet. In Apache-Umgebungen begrenze ich Keep-Alive so, dass lange Leerlauf-Verbindungen nicht den Thread-Pool binden. LiteSpeed abstrahiert vieles davon, spielt seinen Vorteil aber erst mit LSAPI voll aus.

OPcache, JIT und Preloading: was wirklich hilft

OPcache ist Pflicht. In der Praxis dimensioniere ich opcache.memory_consumption großzügig (z. B. 192–512 MB je nach Codebasis) und erhöhe opcache.max_accelerated_files, damit keine Evictions auftreten. Für Builds, die selten deployen, deaktiviere ich validate_timestamps oder setze ein höheres revalidate_freq, um Syscalls zu sparen. Preloading kann Frameworks beschleunigen, entfaltet aber vor allem bei konsistenter Autoload-Struktur Wirkung. Das JIT von PHP bringt bei klassischen Web-Workloads selten Vorteile und kann sogar RAM kosten; ich schalte es nur zu, wenn Benchmarks unter Realbedingungen das bestätigen.

Queue-Management und Backpressure

Die meisten Engpässe entstehen nicht in der CPU, sondern in der Warteschlange. Wenn mehr Requests eintreffen, als Worker abarbeiten können, wächst die Queue und die P95/P99-Latenz schießt hoch. Ich stelle sicher, dass pm.max_children groß genug ist, um typische Peaks zu schlucken, aber klein genug, um RAM-Reserve zu halten. pm.max_requests setze ich moderat (z. B. 500–2000), damit Memory-Leaks keine Langläufer erzeugen. Der listen.backlog muss zum Webserver-Backlog passen, sonst droppt der Kernel Verbindungen unter Last. Wer die Ankunftsrate (Requests pro Sekunde) und die mittlere Servicezeit misst, kann mit einfacher Kapazitätsrechnung beurteilen, ab welcher Concurrency die Latenz kippt.

Timeouts, Uploads und Langläufer

Lange Uploads oder API-Calls blockieren Worker. Ich definiere klare Grenzen: max_execution_time und request_terminate_timeout in FPM verhindern, dass defekte Requests ewig laufen. Auf Proxy-Ebene synchronisiere ich proxy_read_timeout/fastcgi_read_timeout mit den FPM-Limits, damit es nicht zu verfrühten 504 kommt. Große Uploads streame ich, begrenze post_max_size und upload_max_filesize streng und plane dedizierte Endpunkte, damit der restliche Traffic nicht leidet. Für cron-ähnliche Langläufer verschiebe ich Arbeit in Queues oder CLI-Jobs, statt Frontend-Worker minutenlang zu blockieren.

Sessions und Locking im Detail

PHP-Sessions sind standardmäßig sperrend. Ein zweiter Request desselben Nutzers wartet, bis der erste die Session freigibt – fatal für WooCommerce, wenn parallel Ajax-Calls laufen. Ich beende Session-Schreibzugriffe früh mit session_write_close(), sobald keine Mutationen mehr nötig sind. Mit Redis als Session-Backend sinkt die I/O-Latenz, aber Locking-Regeln bleiben wichtig. Hinter Load-Balancern entscheide ich bewusst zwischen Sticky Sessions (einfach, weniger skalierbar) und stateless Patterns mit Objekt-Cache, damit horizontale Skalierung sauber greift.

Monitoring und Fehlersuche

Ohne Telemetrie ist Tuning Blindflug. Ich aktiviere FPM-Status und Slowlogs pro Pool, um Engpässe zu sehen und Queries zu identifizieren, die auffallen.

; pro Pool
pm.status_path = /status
ping.path = /ping
ping.response = pong
request_slowlog_timeout = 3s
slowlog = /var/log/php-fpm/www-slow.log
pm.max_requests = 1000

Steigen 502/504-Fehler, prüfe ich zuerst: Ist die FPM-Queue voll? Gibt es CPU-Steal oder Swap? Passt das Webserver-Timeout zu den FPM-Limits? Ein Blick in smaps pro Worker zeigt reale RSS-Belegung, während netstat/ss Backlog-Überläufe aufdeckt. Für OPcache beobachte ich die Hit-Rate und die Zahl der Revalidierungen, um Evictions zu vermeiden.

Container, Sockets und Ressourcen-Grenzen

In Containern nutze ich meist TCP statt Unix-Sockets zwischen Webserver und FPM, um Namespace-Grenzen zu vermeiden und Load-Balancing zu erleichtern. Wichtig sind konsistente cgroup-Limits: Wenn der Container nur 1–2 GB RAM hat, muss pm.max_children entsprechend kleiner sein, sonst greift der OOM-Killer. CPU-Quotas beeinflussen die Reaktionszeit stark; ich plane Headroom und verifiziere unter Limit die P95-Latenz. NUMA- und Core-Affinity-Themen werden bei sehr hoher Last relevant, während LSAPI in LiteSpeed-Setups viel davon intern optimiert.

Multi-PHP-Versionen und Erweiterungen

Viele Hosts fahren mehrere PHP-Versionen parallel. Ich isoliere Pools pro Version und halte Erweiterungen schlank. Jedes zusätzliche Modul erhöht RAM pro Worker und kann die Startzeit verlängern. Unbenutzte Extensions entferne ich konsequent; das bringt oft mehr als ein kleinerer pm.max_children-Zuwachs. Beim Upgrade plane ich kurze Warmup-Phasen für OPcache ein, damit nach dem Deploy nicht alle Nutzer gleichzeitig Kaltsstarts erleben.

Ram-Diät und realistische Kapazitätsplanung

Statt pauschaler Werte ermittle ich den mittleren und oberen RAM-Bedarf pro Worker mit Live-Traffic. Daraus leite ich ab: (verfügbarer RAM – System/DB/Caches) / RAM pro Worker = maximale sinnvolle pm.max_children. Zusätzlich halte ich 15–25 % Reserve für Burst, Kernel-Cache und unvorhergesehene Spikes. Wenn die Anwendung sporadisch Speicher aufbläht, ziehe ich die Grenze tiefer oder kürze pm.max_requests, um Prozesse häufiger zu recyceln.

Teststrategie: Reproduzierbare Last und reale Muster

Ich nutze Testprofile, die kalte und warme Caches mischen, GET/POST kombinieren und Concurrency stufenweise erhöhen. Wichtig: Erst mit aktivem OPcache und realistischen Think-Times sehe ich, ob das System unter Nutzungsverhalten stabil bleibt. Ein Ramp-Up über mehrere Minuten verhindert künstliche Peaks beim Start. Die Auswertung fokussiert auf TTFB und P95/P99, nicht nur auf Durchschnitts-RTT oder reine req/s.

Fehlerbilder aus der Praxis

  • Viele 504 unter Peak: FPM-Queue voll, Backlog zu klein, Timeouts am Proxy enger als in FPM.
  • Stottern bei Deploys: OPcache-Verdrängungen, fehlendes Warmup, zu kleine opcache.memory_consumption.
  • Gute Durchschnittswerte, schlechte P99: Zu viele Langläufer (I/O, externe APIs), fehlendes Circuit-Breaking.
  • Hohe CPU, geringe req/s: Session-Locks oder nicht gecachte Datenbankabfragen, die seriell limitieren.

Betriebssicherheit und Rollback

Jede Änderung am Handler oder den Pool-Parametern fahre ich mit Feature-Flags oder stufenweise aus. Ich behalte Error- und Slowlogs, P95 und Fehlerquote im Blick und definiere einen klaren Rückbau, falls Metriken kippen. Ein zweiter Pool mit identischer Version, aber anderen Parametern ermöglicht schnellen A/B-Wechsel ohne Downtime. Unter Volllast bewährt sich eine kurze, automatische Reduktion der Concurrency (Backpressure), statt neue Worker unkontrolliert zu starten.

Kurz zusammengefasst

Für dynamische Sites mit vielen gleichzeitigen Nutzern bevorzuge ich LSAPI auf LiteSpeed, während PHP-FPM auf Apache oder Nginx den besten Allrounder gibt. mod_php bleibt ein Spezialfall für sehr einfache Projekte ohne strenge Isolation. Entscheidend sind realistische Tests mit warmem OPcache, sinnvollen Pool-Limits und sauberem Caching. Wer Latenzen zuverlässig drückt, misst P95/P99 und reagiert zuerst auf Tail-Probleme statt auf Durchschnittswerte. So erreicht eine Anwendung spürbar schnellere Antworten und mehr Reserven für Peak-Traffic.

Aktuelle Artikel