The PHP-FPM status page shows, for a specific pool, how many workers are active and whether there are any requests waiting. However, for a robust performance analysis, you need more than just a single snapshot: Compare values over time and cross-reference them with response times, logs, and resource usage. Queue and Available Workers They help pinpoint a bottleneck, but they don't reveal its cause on their own. Set up protected status access and check whether it actually leads to your application's pool.
What the status page shows about the pool
The PHP-FPM status page shows how a specific pool PHP requests processed: including, among other things, how many processes are active or idle, and whether any requests are queued. This requires that the application is actually served by PHP-FPM. The PHP version displayed via the command line alone does not indicate this, nor does it indicate the version of the corresponding FPM service.
Therefore, first determine the FPM version being used and the pool to which the web server forwards the application. This includes the Unix socket or TCP listener being used and the routing configuration in the relevant virtual host. This mapping is important to ensure that a subsequent status query does not inadvertently refer to a different pool.
If a server runs multiple pools, the output applies only to the specific pool being queried and not automatically to all PHP applications. In shared hosting, you may not have the necessary permissions to configure the pool or web server. In that case, you’ll need the provider to make the status page or similar metrics available in a secure manner.
A retrieval is, first and foremost, a Snapshot: Short queues may appear and disappear between two queries. Other values count events since the FPM startup; they are reset upon a restart. Therefore, to ensure a meaningful history, store the retrieval time and pool identity along with the values.
This page does not account for the entire wait time in the browser. The network, web server, database, and external services can also contribute to the response time. It is therefore a starting point for diagnosing the PHP-FPM pool, not a comprehensive performance test of the website.
Understanding Workers and Process Managers
The process manager determines how the pool allocates its workers. In the case of static their number remains constant. dynamic adjusts the number to meet demand within configured limits; ondemand starts processes as needed. The amount of free capacity you can expect therefore also depends on the selected operating mode.
An active process is currently processing a request; an idle process is ready to take on work. Having many active workers is not necessarily a problem: a fully utilized pool can process requests quickly. This observation becomes more meaningful when requests are queued, response times are increasing, and there are hardly any idle processes available.
Even a temporary shortage in the reserve is not, in and of itself, proof of a lasting bottleneck. Compare repeated calls with the configured Process Limit and the times when users actually notice delays. This helps you distinguish a brief spike in traffic from a recurring overload.
More workers can process more requests in parallel, but they require additional memory and can place a heavier load on databases or external services. If many processes are waiting for the same slow dependency, raising the limit won't eliminate the root cause. Therefore, check your resources and request duration before you pm.max_children change.
To understand the division of responsibilities within the hosting stack, it is helpful to compare NGINX Unit and PHP-FPM. It complements the architectural perspective; you must still check the actual status values and Process Manager settings in the FPM pool that is actually in use.
Securing Status Access and FastCGI
The status output may reveal sensitive information about requests and resources. In particular, process details may contain request URIs that allow inferences to be drawn about the functions called or the parameters transmitted. Therefore, treat this page as a diagnostic interface rather than a public status dashboard.
Limit the HTTP Access for internal requests or explicitly known client IP addresses. When doing so, verify which address the web server actually sees as the client if a proxy is in place. The protection must apply to the routing of the status page and should be verified before approval.
Regardless of that, secure the FastCGI Access ... On its own. For a Unix socket, ownership and permissions are relevant; for TCP, the network binding and authorized clients must be checked. A lock on the web server does not protect a FastCGI port that is separately accessible from an untrusted network.
The PHP project has documented an XSS vulnerability in the FPM status output as CVE-2026-6735. Fixed versions include PHP 8.4.21 and 8.5.6. For other version branches and distribution packages, check the respective security status or backported patches instead of assuming protection based solely on the displayed version number.
An update does not replace access restrictions: Even a corrected status page can still reveal operational details. Keep both HTTP access and the listener restricted to the intended user group, and take these two layers of protection into account when making future changes to the routing.
Host the status page securely
First, determine which FPM pool is handling the application in question and through which socket or TCP address the web server accesses it. If there are multiple pools, the status query belongs to the pool to which it is forwarded. The PHP version displayed on the command line alone does not indicate which FPM service is responsible for the application.
In the configuration file for the relevant pool, the following excerpt enables the Status Path. It is not a PHP file that you need to create in the documents directory. The snippet is a suggested configuration and assumes that you have permission to edit the pool configuration.
Set up an appropriate route in the web server that forwards requests to this path directly to the designated pool via FastCGI. The standard application routing must not intercept the request. Restrict HTTP access to internal requests or known client IP addresses, and secure the FastCGI socket independently of this through permissions, network binding, and authorized clients.
Before the rollout is released, verify both the web server and FPM configurations using the testing procedures specified for your environment. Make sure you are modifying the correct service and pool, and that the access restriction also applies to the status path. Simply setting a path does not make the output accessible via HTTP.
For an environment that is already set up and protected locally, the following terminal command reads the JSON output. It assumes that a matching local HTTP virtual host is accessible at the specified address. Otherwise, you’ll need to adjust the address, host routing, and TLS (if applicable) to match your environment; running this command does not change any configuration.
In your response, pay particular attention to the pool name. An error message or unexpected application output may indicate incorrect routing; an access restriction may also prevent the request from being processed. Check the relevant web server configuration and logs before hastily removing the protection.
How to Read and Calculate Key Metrics Correctly
The status values describe different time periods: Some show the status at the time of retrieval, while others count events or record a maximum value since startup. For diagnostic purposes, this distinction is more important than a single unusual value. The following table categorizes the key data points.
| Key figure | Meaning | Kind | Do not confuse with |
|---|---|---|---|
| active processes / idle processes | Active or available processes | Snapshot | The mere presence of many active processes does not, in itself, indicate a bottleneck. |
| listen queue | Requests Currently Pending | Snapshot | A previous peak says nothing about the current line. |
| max listen queue | Longest queue observed since launch | Maximum value | Inquiries no longer have to wait. |
| list queue length | Queue Capacity | Configuration-Related Limit | Capacity is not the current number of pending requests. |
| accepted conn | Accepted Connections | Cumulative Counter | This value does not represent the number of external page views. |
| max children reached | Events Upon Reaching the Process Limit | Cumulative Counter | A value of zero is not a reliable indication that the problem has been resolved when using `static`. |
| slow requests | Queries that have reached the configured slowlog threshold | Cumulative Counter | Zero does not prove that all requests were fast. |
For a Connection rateDo you subtract two values from accepted conn Subtract one from the other and divide the difference by the elapsed time. Hypothetical calculation example (not based on actual measurements): If the counter increases from 12,000 to 12,600 within 60 seconds, this results in an average of ten assumed connections per second. Neither page views nor application latency can be directly derived from this.
Store the time and pool ID for each measurement point. After an FPM restart, the status values are reset; therefore, a difference across this break is not a valid rate. Detect a decreased counter or a changed start time and restart the calculation for the new time period.
At max children reached the process manager is crucial: The sample configuration for PHP 8.4.21 describes the counter for `dynamic` and `ondemand`. For `static`, you must not interpret a zero value as evidence of available capacity. For slow requests The threshold and slowlog must be configured correctly; the threshold determines which long requests are logged at all.
Compare Output Formats and Process Details
The short version is useful for getting an overview of the entire pool. The key factor in choosing the format is whether you want to read the values manually or process them regularly using a monitoring system. The parameter full extends the output to include process details; it is not a standalone exchange format.
| Issue | Intended use | Limit or Prerequisite |
|---|---|---|
| Text | Quick Manual Check of Pool Values | To make comparisons over time, record the number of accesses and the dates and times. |
| JSON | Structured, Automated Analysis | Protect access and verify the format using the monitoring client. |
| OpenMetrics | Integration with compatible monitoring systems | PHP 8.1 or later; check actual output and client compatibility. |
| full | Additional Information on Individual Processes | For OpenMetrics, do not assume that individual process data is available without first verifying the installed version. |
The PHP Manual also documents XML and HTML. When performing automated queries, check the actual FPM version installed and its output before relying on specific fields or process details. In particular, you should check the combination of OpenMetrics and full Check it in your own version, rather than making blanket assumptions about individual process data.
The Request duration In the Full output, the value is given in microseconds. For an active process, it indicates the duration of the request currently being processed; for an inactive process, it refers to the last request processed. A high value for an idle worker therefore does not mean that the worker is still processing the request.
The Fields last request cpu and last request memory are reported as zero for busy processes because they are evaluated only after the request has completed. These zero values therefore do not indicate a lack of CPU or memory usage. Repeated queries can show whether a process remains busy for an extended period; however, they are no substitute for a complete application trace.
Investigating Queues and Slow Requests
If the queue If this happens repeatedly—while many processes are active and only a few are free—a fully utilized pool is a plausible working hypothesis. A single check isn't enough: Compare multiple time points and see if response times for requests are increasing at the same time. The maximum queue size alone does not indicate whether there are still requests waiting.
Compare the time period using FPM logs, CPU utilization, and available memory. Also consider the database, cache, and external services: If PHP is waiting for a slow dependency, workers remain busy, even though additional CPU power alone may not solve the problem. The status page shows the load, but does not reliably indicate its cause.
Call the protected full output repeatedly during a noticeable phase. A long request duration for the same active process may indicate a worker that has been busy for an extended period; check the process status, because for an inactive process, the duration refers to its last request. The PID, URI, and script help with identification but do not provide a complete trace.
Especially with a front-end controller, the same script name can cover many different application functions. Therefore, supplement this observation with application tracing and a properly configured Slowlog. Its threshold determines which long requests are logged; the absence of an entry does not prove that all requests were fast. The post on Analyzing the PHP-FPM Slowlog.
For troubleshooting, note the time window and the affected pool. This allows you to check, for example, whether a slow database query coincides with the workers that were occupied at the time, or whether the queue had already started to grow before that. A correlation narrows down the search, but it does not replace the need to examine the specific request.
Monitoring and Outages of the Status Page
For recurring load spikes, regular, protected queries provide more meaningful insights than occasional one-off checks. JSON is well-suited for automated processing; OpenMetrics is an alternative if the installed PHP version and the monitoring client are compatible. For each measurement point, record the time and the pool’s identifier so that you don’t accidentally compare different pools.
Treat Missing Retrievals as separate events rather than as zero values. A gap may be due to network issues, access restrictions, or the status service; it does not in itself indicate an empty pool or an application failure. Therefore, be sure to log errors and timeouts from the retrieval as well, so that the gap remains visible during subsequent analysis.
Also, be aware that cumulative counters are reset after an FPM restart. A negative difference between two values does not indicate a negative connection rate; restart the calculation after the reset and take the interrupted interval into account. The start time and pool assignment also help to contextualize such a break in the trend.
If the status query runs through the same pool as the application, it can wait on its own if the workers are exhausted. For this situation, pm.status_listen A separate FastCGI listener with an independently operating internal pool. It can enable status diagnostics while the main pool is busy; however, it does not increase the main pool's processing capacity.
The additional listener requires explicitly assigned, protected web server routing. Also secure its FastCGI access and, after a change has been approved, verify that the request actually returns the desired pool status. This keeps the diagnostic process separate from the normal application path without making the status data publicly accessible.
Review Findings and Select Actions
An FPM ping and the status page answer different questions. The ping shows whether FPM is responding to the corresponding request; it does not provide equivalent information about available workers or queued requests. A successful ping alone is therefore not an indication that the application pool is not overloaded.
If process metrics do not match logs or other observations, first check the pool assignment, the retrieval time, and whether a restart is necessary. Next, compare the values with other available process and operational data. Initially treat the discrepancy as an open issue rather than immediately concluding that there is a specific cause or that a configuration change is necessary.
If repeated full retrievals and slowlog entries show the same long request patterns, first investigate the affected application paths. If, on the other hand, the delay is occurring at a database or an external service, analyzing those can be more effective than changing the number of workers. The key factor is whether the measure addresses the observed root cause, not just a single symptom.
An adjustment to pm.max_children This is an option if the pool is demonstrably operating at its limit and the CPU, memory, and downstream services can handle additional concurrency. More workers require resources and can increase the load on these services. Therefore, there is no one-size-fits-all number; the process manager's operating mode must be taken into account in the evaluation.
After a change has been deployed, compare the same pool again under load conditions that are as similar as possible: Queues, response times, errors, and resource consumption all go hand in hand. Also note if a measure does not result in an improvement or places a greater load on a dependency. Only this Before-and-After Comparison allows for a well-reasoned decision on how to proceed.
Sources and Current State of Knowledge
Status of the research:
Research status: November 4, 2026. According to the PHP manual, OpenMetrics is available starting with PHP 8.1; check the specific release and security status of the FPM version in use.
https://www.php.net/manual/en/fpm.status.php
https://www.php.net/manual/de/install.fpm.configuration.php
https://www.php.net/install.fpm.configuration
https://github.com/php/php-src/security/advisories/GHSA-7qg2-v9fj-4mwv
https://github.com/php/php-src/blob/php-8.4.21/sapi/fpm/www.conf.in




