PHP-FPM Status Logging and Slow Log Tuning on AlmaLinux 9

Why this matters on a live VPS
PHP-FPM status logging gives you three things operators use all the time: pool visibility, proof of slow requests, and a cleaner way to tell whether a delay starts in PHP or upstream in Nginx. On a fresh AlmaLinux 9 VPS, that means you can stop guessing and start tracing the bottleneck. If a customer reports slow checkout, you can check the FPM status page, read the slow log, and decide whether to add workers, raise timeouts, or fix the application.
This tutorial uses AlmaLinux 9 because it is a current RHEL-compatible platform with dnf, systemd, firewalld, and SELinux. The same PHP-FPM approach also fits Hostperl VPS hosting setups where you need hard evidence before a migration, launch, or support escalation.
Connect and confirm the operating system
On your local computer, connect with the example below. Replace 203.0.113.10 with your server's real public IP.
ssh root@203.0.113.10If your hosting account gives you a non-root SSH user first, use that account instead. Keep the first root session open until the new login is verified.
On the VPS as root, confirm the OS before you change packages or service names.
cat /etc/os-releaseYou should see AlmaLinux 9 in the output. If you are on Debian or Ubuntu instead, the package names and SELinux steps differ, so stop here and use an AlmaLinux or Rocky Linux server for this guide.
Update the server and install PHP-FPM tools
On the VPS as root, refresh packages and install PHP-FPM plus the Nginx stack used for verification. The commands below install a current PHP runtime, the FastCGI service, and a few tools for checking logs and HTTP responses.
dnf -y update
dnf -y install php php-fpm php-cli nginx curl policycoreutils-python-utilsAfter installation, confirm the versions you are about to tune.
php -v
php-fpm -v
nginx -vFor Hostperl customers running production web apps, this is the point where you should verify that your deployment rollback plan and application logs are already in place before changing request handling.
Create a non-root admin and keep root as fallback
On the VPS as root, create a sudo-capable admin account named deploy. Do not disable root yet; test the new login first.
useradd -m -G wheel deploy
passwd deploySet a strong password when prompted. If you use SSH keys, create the SSH directory and move the public key in with the correct ownership.
mkdir -p /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
cat > /home/deploy/.ssh/authorized_keys <<'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyReplaceThisWithYourOwn deploy@laptop
EOF
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.sshOpen a second terminal on your local computer and test the new account before you change any SSH policy.
ssh deploy@203.0.113.10
sudo -iu deploy
sudo whoamiSuccessful output should show root from sudo whoami. If that works, you can keep using the new account for the rest of the guide.
Prepare a safe PHP-FPM pool configuration
On the VPS as root, back up the default pool file before editing it.
cp -a /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bakNow open the pool file and add the status, ping, and slow-log settings. These values expose useful diagnostics without turning PHP into a noisy debug service.
nano /etc/php-fpm.d/www.confReplace the relevant lines or append the following values inside the [www] pool.
[www]
user = nginx
group = nginx
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500
pm.status_path = /fpm-status
ping.path = /fpm-ping
ping.response = pong
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
access.log = /var/log/php-fpm/www-access.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = onSave and exit the editor. On nano, press Ctrl+O, Enter, then Ctrl+X.
These values keep the pool readable in production. The status endpoint shows active and idle workers, the ping path confirms the service answers quickly, and the slow log records requests that run longer than five seconds.
Create log directories and SELinux labels
On the VPS as root, create the log directory and make sure PHP-FPM can write to it.
mkdir -p /var/log/php-fpm
chown -R nginx:nginx /var/log/php-fpm
chmod 750 /var/log/php-fpmNow fix the SELinux context for the log directory and allow the web server to connect to PHP-FPM over the local socket.
semanage fcontext -a -t httpd_sys_rw_content_t '/var/log/php-fpm(/.*)?'
restorecon -Rv /var/log/php-fpm
setsebool -P httpd_can_network_connect 1If you later connect PHP to a database or upstream API, this SELinux boolean avoids a common false failure where PHP works in tests but not under the web server.
Enable PHP-FPM status logging and start the services
On the VPS as root, test the PHP-FPM syntax before reloading. This catches typos before they take the pool down.
php-fpm -tYou want a message that says the configuration test is successful. Then enable and start PHP-FPM and Nginx.
systemctl enable --now php-fpm
systemctl enable --now nginxCheck both services and confirm PHP-FPM owns the expected socket.
systemctl status php-fpm --no-pager
systemctl status nginx --no-pager
ss -lpn | grep php-fpmAt this point, php-fpm should be running, and the socket under /run/php-fpm/www.sock should be present.
Expose the status page through Nginx
On the VPS as root, create a small Nginx server block that serves a status page only from localhost. This keeps the diagnostics endpoint private while still letting you test it from the server.
nano /etc/nginx/conf.d/php-fpm-status.confUse this exact file content.
server {
listen 127.0.0.1:8080;
server_name localhost;
location /fpm-status {
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location /fpm-ping {
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}Save and exit, then test the Nginx syntax before reloading.
nginx -t
systemctl reload nginxTest the endpoints locally on the VPS. You should see status output and the word pong.
curl -s http://127.0.0.1:8080/fpm-status
curl -s http://127.0.0.1:8080/fpm-pingIf the status page returns lines like pool: www and active processes, the endpoint is working.
Run a controlled PHP test page
On the VPS as root, create a simple test file so you can confirm Nginx passes requests to PHP correctly.
mkdir -p /usr/share/nginx/html
cat > /usr/share/nginx/html/info.php <<'EOF'
<?php
phpinfo();
EOF
chown -R nginx:nginx /usr/share/nginx/html
restorecon -Rv /usr/share/nginx/htmlNow request the page from the server itself.
curl -I http://127.0.0.1/info.phpA 200 OK response tells you PHP execution is alive. Remove this file after validation if you do not want to leave a public diagnostic endpoint in place.
rm -f /usr/share/nginx/html/info.phpOpen the firewall safely
On the VPS as root, allow only the services you actually need. If this server will serve web traffic, open HTTP and HTTPS first. Do not remove SSH access until you have a tested secondary login.
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-allIf you are still testing locally, you can also keep the status port private by leaving 8080 closed to the internet. That is the safer choice for most customer sites on Hostperl dedicated or managed VPS hosting.
Read the slow log and interpret the first incident
On the VPS as root, force a slow request if you have a test script, or wait for live traffic and then inspect the log file. The slow log records the stack trace or script path that crossed the timeout threshold.
tail -f /var/log/php-fpm/www-slow.logYou should see entries only when requests exceed five seconds. If the file stays empty during normal traffic, that is a good sign. If it fills quickly, you likely have application code, database latency, or external API waits to fix.
For a broader logging workflow, this pairs well with the log handling patterns in Nginx log rotation and app log debugging, especially when you want clean retention without losing incident evidence.
Troubleshoot the common failure points
On the VPS as root, use the commands below when something does not work.
1. PHP-FPM will not start
journalctl -u php-fpm -xe --no-pager
php-fpm -tIf the journal shows a parse error, fix the config file and run php-fpm -t again before restarting.
2. Nginx returns 502 Bad Gateway
systemctl status php-fpm --no-pager
ss -lx | grep www.sock
ausearch -m avc -ts recentIf SELinux blocked the socket or file write, the AVC log will show it. Recheck your semanage and restorecon steps, then reload the services.
3. The status page is blank or 404
curl -v http://127.0.0.1:8080/fpm-status
nginx -T | grep -n fpm-statusIf Nginx does not load your config, correct the file under /etc/nginx/conf.d/ and run nginx -t again.
4. The slow log never appears
ls -ld /var/log/php-fpm
ls -l /var/log/php-fpm
getenforceIf permissions or SELinux are wrong, PHP-FPM cannot create the file. Restore ownership to nginx:nginx and apply the label again.
Check reboot persistence and leave a safe rollback path
On the VPS as root, confirm the services will come back after a reboot.
systemctl is-enabled php-fpm
systemctl is-enabled nginxThen schedule a maintenance reboot only after a backup or snapshot exists. After the reboot, run the same status commands again. If the pool fails to return, restore the backup file and roll back the config.
cp -a /etc/php-fpm.d/www.conf.bak /etc/php-fpm.d/www.conf
php-fpm -t
systemctl restart php-fpmThat rollback is simple on purpose. A clean revert is better than trying to debug an unstable pool during a customer incident.
If you want PHP-FPM diagnostics on a VPS that is ready for real customer traffic, Hostperl can provide the right platform and support path. Start with Hostperl VPS hosting for an app server, or pair it with managed shared hosting when your workload fits a lighter deployment model.
FAQ
What does PHP-FPM status logging show?
It shows pool health, active and idle workers, request counts, and whether workers are hitting saturation. That gives you a fast answer when a site feels slow.
Should the status page be public?
No. Keep it on localhost or restrict it to an internal network. It is a diagnostic endpoint, not a customer-facing page.
Why use a slow log?
The slow log records the file and stack path for requests that exceed your timeout threshold. That helps you separate code delays from network or database delays.
Can I use these steps on Debian or Ubuntu?
The PHP-FPM ideas are the same, but package names, service paths, and SELinux handling differ. This tutorial is written for AlmaLinux 9 and other RHEL-compatible systems.
What should I check first if I get a 502 error?
Check systemctl status php-fpm, confirm the socket exists, then review SELinux AVC messages with ausearch. In most cases, the root cause shows up there quickly.
For related planning work, you can also review PHP-FPM pool tuning for shared and VPS hosting and Core Web Vitals for hosting sites when you are deciding whether to fix PHP settings, code paths, or infrastructure sizing next.
