pm.max_requests is not specific to any Process Manager (
pm) mode. Its benefits are to respawn worker processes after the specified amount of requests they handle individually.
It could avoid memory leaks in extreme cases, but usually it just frees up memory allocations accumulated when memory-hungry scripts were executed. Memory allocations pile up and the total amount of memory allocated grows, but is only freed on exit (thus when respawn).
As you put it, you seem not to have activated
pm.max_requests when using
pm static. You should have seen a difference, and certainly more than a flat line.
pm dynamic has the added benefit of stopping workers depending on the number of idle processes amongst them (
pm.max_spare_servers), which are a kind of a metric measuring instant load. Stopping useless processes frees the associated allocated memory at the cost of process handling (CPU), which
pm.min_spare_servers counteracts ensuring a safety cushion in case of spikes, maintaining idle workers ready to process requests.
Now, if you really are looking after your memory,
pm ondemand is more aggressive, (de)spawning processes as (not) needed (anymore). This mode is the closest to the edge, since it won't absorb spikes as well as
pm dynamic, but it is the leanest on memory consumption (with the counterpart of using more CPU for process management purposes).
Memory allocations stack up for any worker process. If a particular request was memory-hungry, it will top the processing worker memory allocation, and this won't be freed until the process stops.
pm.max_requests to recycle processes, whatever mode you use.
pm.dynamic will recycle processes on another criterion which is load, and will kill processes when too much of them are idling. Having a higher processes turnover is more likely to prevent them being too much memory-hungry, at the cost of more CPU cycles used for processes management.