Hello everyone,

I’d like to propose adding a new configuration directive, tentatively
called *pm.max_memory*, to PHP-FPM. This directive would allow
administrators to specify a per-child memory usage limit, after which the
PHP-FPM child process would gracefully exit or restart.
Background and Rationale

In many production environments, especially those handling long-running or
memory-intensive processes, *memory leaks* (whether in extensions,
libraries, or user code) can slowly accumulate. We already have tools like
pm.max_requests that recycle processes after a certain number of requests,
but there are scenarios in which memory usage might skyrocket within fewer
requests—or memory might slowly climb in a way that doesn’t align well with
request counts alone.

A setting like pm.max_memory could:

   1. *Mitigate slow leaks:* By enforcing a hard memory cap at the process
   level, ensuring no single worker balloons in size over time.
   2. *Provide more granular control:* If certain scripts or pools are
   known to be memory-intensive, an admin could set a memory limit that’s
   appropriate for that usage pattern, rather than tying it only to request
   counts.
   3. *Complement system-level controls:* While cgroups and container
   memory limits exist, a built-in FPM mechanism can be friendlier than a
   system OOM kill, which might be abrupt and less predictable.

Proposed Behavior

   - A new config directive, *pm.max_memory*, which, if set to a value
   above 0, indicates the maximum amount of RAM (in bytes) a PHP-FPM worker
   process is allowed to use (resident set size or a similar metric).
   - After handling a request, each worker would check its own memory
   usage. If it exceeds the threshold, it would gracefully exit or be
   terminated by the master process before picking up a new request.
   - By default, this setting could be *disabled* (pm.max_memory = 0), so
   it does not affect existing installations.

Implementation Details and Challenges

I am not proposing to implement this feature myself—I’m more of a sysadmin
and don’t have the necessary C knowledge to patch php-src. However, here
are some thoughts on what the implementation might involve:

   1. *Measuring memory usage:* Likely via getrusage(), mallinfo() (on some
   platforms), or reading from /proc/self/statm on Linux.
   2. *Graceful shutdown logic:* Ensuring no ongoing requests are abruptly
   killed, or at least minimizing the chance of partial request handling.
   3. *Platform differences:* Some OSes might provide different APIs for
   measuring process memory usage. We’d need consistent cross-platform
   behavior or documented differences.
   4. *Interaction with pm.max_requests:* If both are set, a worker would
   exit on whichever limit it hits first (memory or request count).

Alternatives

   - *Using pm.max_requests:* Currently the main workaround to mitigate
   leaks, but it’s less precise and can’t handle large memory spikes that
   happen quickly.
   - *System-level OOM or cgroups:* This approach can kill the entire pool
   or container, which is often more disruptive than recycling a single worker.

Request for Feedback

I’m posting this proposal to gather feedback on feasibility and interest.
If there’s enough support, I’d be happy to collaborate with anyone who can
handle the technical side—writing up a formal RFC on the wiki or working on
a patch. If there’s a consensus that this is better handled elsewhere
(system-level or container-level controls), or that pm.max_requests is
sufficient, please let me know your thoughts.

*Key questions*:

   1. Would a built-in memory cap be beneficial for a significant subset of
   PHP-FPM users?
   2. Are there any major technical hurdles or objections to this approach?
   3. Does anyone have suggestions on how best to measure memory usage
   accurately and portably across different platforms?

Thank you for reading and considering this idea. I look forward to hearing
your insights and am happy to clarify or discuss any aspect of this
proposal further.

Best regards,
Sincerely,
Arkadiy Kulev (Ark)

Reply via email to