Apache, Nginx and PHP-FPM each include a lightweight status page that shows, in real time, how many connections and workers are busy. When a site slows down under load, these pages answer the key question in seconds: is the web server out of workers, is PHP out of children, or is the bottleneck elsewhere?
Before you start
- Root access to a VPS running Apache or Nginx with PHP-FPM.
- The status pages reveal internal details, so they must be restricted to localhost or your IP.
Nginx stub_status
- Check the module is built in:
nginx -V 2>&1 | grep -o with-http_stub_status_module. - Add a local-only server or location:
server { listen 127.0.0.1:8081; location = /nginx_status { stub_status; } } - Reload and read it:
curl -s http://127.0.0.1:8081/nginx_status
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106- Active connections: all open client connections.
- accepts / handled: should be equal. If handled is lower, Nginx hit
worker_connectionsor a file limit. - requests: total requests; divide the change by time for requests per second.
- Reading / Writing / Waiting: reading request headers, sending responses (or waiting on PHP), idle keep-alive. High Writing with low traffic often means a slow backend.
Apache mod_status
- Enable the module:
sudo a2enmod status(on AlmaLinux it is loaded by default). - Restrict it, e.g. in
/etc/apache2/mods-enabled/status.conf:<Location "/server-status"> SetHandler server-status Require local </Location> ExtendedStatus On - Restart, then read it:
curl -s http://127.0.0.1/server-status?auto
Key fields: BusyWorkers and IdleWorkers; when BusyWorkers reaches MaxRequestWorkers, new requests queue. The Scoreboard line shows one character per slot: _ waiting, R reading, W sending reply, K keep-alive, . open slot. A scoreboard full of W means workers are stuck waiting on slow PHP or a slow client.
If a front controller rewrites every URL to index.php, exclude /server-status from the rewrite.
PHP-FPM status page
- In the pool file (e.g.
/etc/php/8.3/fpm/pool.d/www.conf) set:pm.status_path = /fpm-status ping.path = /fpm-ping - Expose it locally through Nginx:
location ~ ^/(fpm-status|fpm-ping)$ { allow 127.0.0.1; deny all; include fastcgi_params; fastcgi_param SCRIPT_NAME $uri; fastcgi_param SCRIPT_FILENAME $uri; fastcgi_pass unix:/run/php/php8.3-fpm.sock; } - Restart PHP-FPM, reload Nginx, then:
curl -s 'http://127.0.0.1/fpm-status?full'
- active processes / max active processes: peak concurrency since start.
- max children reached: how many times the pool hit
pm.max_children. Any value above 0 means requests had to wait. - listen queue: requests waiting for a free child right now. Should be 0.
- slow requests: requests that exceeded
request_slowlog_timeout.
Reading the three together
| Symptom | Likely cause | Action |
|---|---|---|
| FPM listen queue > 0, max children reached rising | PHP pool too small or code too slow | Check slow log; raise pm.max_children if RAM allows |
| Apache BusyWorkers = MaxRequestWorkers | Web server worker limit | Switch to event MPM, raise limit, cache more |
| Nginx Writing high, FPM idle | Slow clients or large downloads | Normal; check bandwidth |
| All idle but site slow | Database, external API or disk | Check MySQL and I/O |
Graph the metrics
Monitoring tools such as Netdata, Prometheus exporters and Zabbix read these pages automatically and keep history. See install Netdata.
FAQ: web server status pages
Is it safe to leave status pages enabled?
Yes, if they are restricted to localhost or trusted IPs.
Does LiteSpeed have a status page?
Yes, real-time stats in the WebAdmin console: LiteSpeed logs and real-time stats.
Do status pages affect performance?
No measurable impact.
