[php-src] Issue #22531: Observed worker state inconsistencies under Apache mod_proxy_fcgi with connection reuse (PHP-FPM 8.5.6)

[email protected] (fidoboy) Wed, 1 Jul 2026 10:21:25 +0000
Newsgroups php.bugs
Message-ID <[email protected]>
Issue: https://github.com/php/php-src/issues/22531
Author: fidoboy

### Description

## Environment

- PHP-FPM: 8.5.6
- Process manager: `pm = dynamic`
- Typical pool configuration:
  - `pm.max_children` defined (value respected and stable)
  - `pm.start_servers`, `pm.min_spare_servers`, `pm.max_spare_servers` standard tuning
  - `pm.max_requests = 500`
- Backend: Apache HTTP Server
- FastCGI handler: `mod_proxy_fcgi`
- Transport: Unix socket
- Relevant proxy configuration:
<Proxy "fcgi://handler/" enablereuse=on flushpackets=on max=10>


## Additional working configuration (mitigating issue)

The following configuration appears to resolve or significantly reduce the observed behavior:


<Proxy "fcgi://handler/" enablereuse=on flushpackets=auto smax=2 max=12 acquire=1000 ttl=10 timeout=60 connectiontimeout=300ms>


---

## Observed behavior (problematic configuration)

When using the simplified proxy configuration with connection reuse enabled:

- Workers in PHP-FPM appear to remain in intermediate states such as `reading headers` longer than expected.
- `/fpm-status` shows discrepancies in perceived worker activity (notably higher "active" states than expected based on external observation).
- Idle/spare worker management appears delayed or not aligned with expected request completion cycles.
- `max_spare_servers` behavior appears inconsistent with expected worker availability under idle load conditions.
- The issue is reproducible and deterministic under sustained use of persistent FastCGI connection reuse.

---

## Observed behavior (tuned configuration)

With explicit tuning of Apache FastCGI proxy pooling parameters:

- Worker state transitions appear consistent and timely.
- Idle/spare worker management behaves as expected.
- No persistent `reading headers` state anomalies observed.
- `/fpm-status` metrics appear stable and consistent with external process observation.

---

## Notes on reproducibility

- Issue is reproducible under Apache `mod_proxy_fcgi` only with:
  - `enablereuse=on`
  - minimal or default proxy pool tuning
- Behavior changes significantly when introducing:
  - `ttl`
  - `acquire`
  - `connectiontimeout`
  - constrained pool size (`smax`, `max`)

---

## Hypothesis (not confirmed)

It is not confirmed whether this behavior is caused by:

- PHP-FPM internal worker state machine handling
- Apache `mod_proxy_fcgi` connection reuse behavior
- Interaction between FastCGI persistent connections and request lifecycle completion signaling

However, the observed behavior suggests a possible desynchronization between:

- actual request completion at PHP execution level
- worker state transition to idle within PHP-FPM
- FastCGI connection reuse lifecycle on the proxy side

---

## Relation to `/fpm-status` discrepancies

It is not confirmed whether this issue is directly related to known discrepancies observed in `/fpm-status` (e.g. inconsistencies in reported active worker counts under certain conditions).

However, both phenomena share a common dependency on:

- worker state transition timing
- FastCGI connection reuse behavior
- request lifecycle completion signaling (`reading headers` / transition states)

This suggests a possible shared underlying factor, although no direct causality is claimed.

---

## Important clarification

This report is based on observations from an Apache + PHP-FPM setup. Equivalent behavior under Nginx has not been directly evaluated in this context, although similar FastCGI reuse patterns may be relevant.

---

## Summary

- Reproducible worker state inconsistencies observed under Apache `mod_proxy_fcgi` with connection reuse enabled.
- Behavior strongly influenced by proxy connection pooling parameters.
- Mitigation achieved via explicit tuning of reuse, TTL, and connection limits.
- Root cause not confirmed; likely interaction between FastCGI reuse lifecycle and PHP-FPM worker state transitions.
- Possible, but unconfirmed, relation to `/fpm-status` inconsistencies.

### PHP Version

```plain
PHP 8.5.7 (cli) (built: Jun 10 2026 20:19:22) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.5.7, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.7, Copyright (c), by Zend Technologies
```

### Operating System

_No response_