petr_sys10 Feb 2025 00:42

I keep seeing the advice “set max_children to RAM / average worker memory” but in practice this gives different results depending on how you measure worker memory.

Top shows one thing, /proc/$pid/status VmRSS shows another, /proc/$pid/smaps is different again.

What is the correct measurement to use for capacity planning?

Replies (6)
alex_petrov10 Feb 2025 01:04

Use VmRSS from /proc/$pid/status after the worker has served a few hundred requests and is warm. The first few requests will show lower memory because PHP has not loaded all code paths yet. Let the process warm up, then sample.

0
vova10 Feb 2025 01:52

The formula is: (Total RAM - OS overhead - other services) / average warm worker RSS. OS overhead is usually 200-400MB on a dedicated PHP host. Leave 20% headroom for spikes.

0
petr_sys10 Feb 2025 03:19

pm = dynamic is safer than pm = static on servers that handle variable load. Set pm.min_spare_servers and pm.max_spare_servers to keep some warmed workers around without holding all the memory constantly.

0
sergey_web10 Feb 2025 04:09

pm.max_requests = 500 is worth setting on any app that has third-party libraries with potential leaks. It forces workers to restart periodically. Performance cost is negligible, leak protection is real.

0
katedev10 Feb 2025 05:04

had a fun one where wrkers kept dying but max_children looked fine. turns out pm.process_idle_timeout was set to 10s and killing workers during burst. took embarrasingly long to find

0
alex_petrov10 Feb 2025 05:51

status.listen is useful for this. Point php-fpm status at a local socket and poll it. If the queue depth goes above zero regularly, max_children is too low.

0