Überarbeitet am 9. September 2026.
Der Ausgangspunkt dieses Artikels war ein langsamer Nextcloud-Login mit 504-Timeouts. Damals habe ich die PHP-FPM-Werte deutlich erhöht. Die Richtung war nicht völlig falsch – aber einen Wert wie pm.max_children = 355 sollte niemand einfach übernehmen.
PHP-FPM muss zur tatsächlichen Maschine und zur Anwendung passen.
Was bedeutet pm.max_children?
PHP-FPM verarbeitet PHP-Anfragen in Worker-Prozessen. pm.max_children legt bei dynamic fest, wie viele PHP-Prozesse maximal gleichzeitig existieren dürfen. Bei static entspricht der Wert sogar direkt der festen Anzahl der Worker.
Zu niedrig: Anfragen müssen warten und im Log kann beispielsweise stehen:
server reached pm.max_children setting
Zu hoch: PHP kann so viel RAM belegen, dass Datenbank, Redis und Betriebssystem in Speicherdruck geraten oder der OOM-Killer Prozesse beendet.
Erst prüfen, ob PHP-FPM wirklich das Problem ist
Ein 504 von Nginx bedeutet nicht automatisch, dass pm.max_children zu klein ist. Auch eine langsame Datenbank, ein externer Dienst, Dateisystem-I/O oder eine einzelne hängende PHP-Anfrage kann dahinterstecken.
Deshalb zuerst Logs ansehen:
journalctl -u php8.4-fpm --since '1 hour ago'
journalctl -u nginx --since '1 hour ago'
Die PHP-Version natürlich an dein System anpassen.
Die richtige Pool-Datei
Unter Debian/Ubuntu liegt der Standard-Pool beispielsweise bei PHP 8.4 hier:
/etc/php/8.4/fpm/pool.d/www.conf
Die relevanten Einstellungen bei pm = dynamic sind:
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 10
Diese Zahlen sind nur ein Beispiel – nicht die Empfehlung für jeden Server.
RAM-Verbrauch eines PHP-Workers messen
Entscheidend ist, wie viel Speicher ein echter PHP-FPM-Prozess unter Last bei deiner Anwendung braucht. Einen groben Durchschnitt kann man beispielsweise so ermitteln:
ps --no-headers -o rss -C php-fpm8.4 | awk '{sum+=$1;n++} END {if(n>0) printf "%.1f MB\n",sum/n/1024}'
Angenommen, ein Worker benötigt durchschnittlich 120 MB. Dann darf man trotzdem nicht einfach den gesamten freien RAM durch 120 teilen. MariaDB/PostgreSQL, Redis, Webserver, Docker-Dienste und das Betriebssystem brauchen ebenfalls Speicher.
Eine vernünftige Rechnung
Beispiel: Von einem Server möchtest du bewusst nur 8 GB für diesen PHP-FPM-Pool reservieren. Ein Worker benötigt im Mittel 120 MB:
8192 MB / 120 MB ≈ 68 Worker
Dann wäre 68 die theoretische Obergrenze innerhalb dieses bewusst reservierten Budgets. Ich würde anschließend noch etwas Luft lassen und unter realer Last beobachten, statt sofort bis ans mathematische Maximum zu gehen.
dynamic, ondemand oder static?
PHP selbst kennt drei Prozessmanager:
- dynamic: hält mehrere Worker bereit und passt ihre Anzahl zwischen Mindest- und Maximalwerten an.
- ondemand: startet Worker erst bei Bedarf. Das spart bei wenig genutzten Seiten RAM, kann aber beim ersten Aufruf etwas mehr Arbeit verursachen.
- static: hält immer exakt
pm.max_childrenWorker. Das ist eher etwas für sehr genau dimensionierte Umgebungen.
Für einen normal ausgelasteten Nextcloud- oder WordPress-Server ist dynamic häufig ein vernünftiger Ausgangspunkt.
Konfiguration testen und neu laden
Nach einer Änderung:
sudo php-fpm8.4 -t
sudo systemctl reload php8.4-fpm
Falls deine Distribution den Testbefehl anders benennt, zeigt systemctl status php8.4-fpm normalerweise schnell, ob der Dienst sauber läuft.
Nicht nur PHP optimieren
Gerade bei Nextcloud bringt es nichts, PHP mit immer mehr Workern zu fluten, wenn Caching oder Datenbank nicht passen. Für Nextcloud habe ich deshalb zusätzlich einen eigenen Artikel zu Redis und APCu.
Nach der Änderung beobachten
Ich würde danach mehrere Dinge kontrollieren:
- taucht
server reached pm.max_childrenweiterhin auf? - wie hoch steigt der RAM-Verbrauch unter echter Last?
- entsteht Swap-Druck?
- werden die Antwortzeiten tatsächlich besser?
Ein größerer Wert ist nur dann eine Verbesserung, wenn das Gesamtsystem dabei stabil bleibt.
Fazit
pm.max_children ist kein Tuning-Regler nach dem Motto „mehr ist schneller“. Der richtige Wert ergibt sich aus realem Speicherverbrauch, Last und dem RAM-Budget, das PHP neben allen anderen Diensten überhaupt bekommen darf. Genau deshalb würde ich heute messen, rechnen, etwas Reserve lassen und anschließend beobachten.
Quelle: PHP-Handbuch: FPM-Konfiguration.
Wie ist deine Meinung?
Schreib gern einen Kommentar unter dem Artikel oder diskutiere mit anderen im Matrix-Kanal:
#dasnetzundich:matrix.org
… hat dies repostet!