Server

PHP-FPM

PHP-FPM is a manager that keeps a pool of PHP worker processes ready to run scripts for a web server such as Nginx. Each worker handles one request at a time.

How it is measured

Enable the status page (`pm.status_path`) and read active, idle and total processes, listen queue length, and 'max children reached'. The pool settings are `pm.max_children`, `pm.start_servers` and `pm.max_requests`.

Size the pool from memory: free RAM for PHP divided by the average worker size. At 80 MB per worker, 2 GB for PHP allows about 25 workers.

Worked example

A WordPress shop has `pm.max_children = 10`. During a promotion, 10 workers are all busy on 600 ms WooCommerce requests, the listen queue reaches 35, and the log writes 'server reached pm.max_children setting (10)'. Visitors see 504s after waiting 60 seconds.

RAM shows 1.4 GB free with workers at 70 MB each, so raising max_children to 18 fits. Page caching for logged-out visitors removed most of the PHP load afterwards.

How it differs

PHP-FPM runs the PHP code. Nginx receives the connection and hands PHP requests over to it. FPM excludes static files, TLS and routing, and Nginx excludes running PHP itself. If workers are full, Nginx is fine but waits, and the proxy log shows long upstream times.

Common errors

Setting max_children by guess and running out of RAM. Leaving it at the default of 5. Using a long request timeout so slow scripts hold workers. Skipping `pm.max_requests` and letting leaky plugins grow. Ignoring slowlog.

In practice

Turn on the FPM status page, check 'max children reached' and listen queue, and compute the pool size from real worker memory. Enable the slowlog with a 3 second threshold and read it after a busy day.

See also

Opcode cache, WordPress

Sources

Count this on a real site.

Watch my website