PHP 8: Modern PHP Development · Performance and Deployment
PHP-FPM and Nginx
Run PHP behind Nginx with a tuned FPM process pool.
PHP-FPM manages a pool of worker processes; Nginx serves static files and forwards PHP requests via FastCGI. Each worker handles one request at a time, so pm.max_children caps concurrency — size it from available memory divided by per-worker memory. Use pm = dynamic or static for steady traffic, enable the status page and slow log, and set request_terminate_timeout to kill runaway requests.
; /etc/php/8.4/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 40 ; ~ (RAM for PHP) / (avg worker RSS)
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 1000 ; recycle workers to contain leaks
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log
request_terminate_timeout = 30s
pm.status_path = /fpm-status
server {
root /var/www/app/public;
location / { try_files $uri /index.php$is_args$args; }
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
internal;
}
location ~ \.php$ { return 404; } # never execute other PHP files
}
Common pitfalls
- Setting
pm.max_childrentoo high and running out of memory (OOM kills). - Letting Nginx execute any
.phpfile, including uploads. - No slow log, making stuck requests invisible.
Key points
- max_children caps concurrency; size by memory
- Only route the front controller to PHP
- Use slow logs and status pages
Further reading: PHP manual: FPM configuration
Go deeper: PHP-FPM and the Shared-Nothing Model in the Request Lifecycle course traces this step of the request, with a production bug and a runnable simulation.
Practice questions
How do you size pm.max_children?
Answer
Measure average worker memory (RSS) under load and divide the memory available for PHP by it, leaving headroom for the OS and other services. Then load test.
What does pm.max_requests do?
Answer
Recycles each worker after N requests, limiting the impact of memory leaks in extensions or long-lived code.
Open in the app to mark lessons complete, take notes and track your progress.