Linux, Web Server & Database
Configure PHP-FPM
Set up PHP-FPM pools properly tuned for your site's traffic and your server's resources.
The Problem
PHP-FPM is running on default settings that aren't matched to your actual traffic or available RAM, leading to either wasted resources sitting idle, or the server running out of workers and queuing requests under load.
About this problem
PHP-FPM's default pool configuration is a generic starting point, not a tuned setup — the key settings (pm.max_children, pm.start_servers, memory limits) need to be calculated against how much RAM each PHP process actually uses and how much RAM the server has available, otherwise you either waste capacity or run out of workers exactly when traffic picks up.
This comes up when a site feels fine at low traffic but slows to a crawl or starts queuing requests the moment visitors increase, or when setting up a new site and wanting it configured properly from the start.
What's Included
- Measuring actual per-process PHP memory usage for your specific application
- Calculating and setting pm.max_children and related values against your server's available RAM
- Choosing the right process management mode (dynamic, static, ondemand) for your traffic pattern
- Testing under simulated load to confirm the pool handles it without exhausting workers
What's NOT Included
- Fixing slow PHP code itself — tuning PHP-FPM manages capacity, it doesn't speed up genuinely slow application logic
- Scaling to multiple servers or load balancing
- Ongoing tuning as traffic patterns change significantly over time
How It Works
- Measure the actual memory footprint of a typical PHP-FPM worker process for this specific application under real load.
- Calculate pm.max_children based on available RAM divided by that per-process memory usage, leaving headroom for other services.
- Choose the appropriate process manager mode — dynamic for variable traffic, static for predictable high load, ondemand for low-traffic sites needing minimal idle resource use.
- Set pm.start_servers, pm.min_spare_servers and pm.max_spare_servers to sensible values matching the chosen mode.
- Load-test or monitor under real traffic to confirm the pool doesn't exhaust available workers or waste significant idle resources.
In practice: you buy the service, send over whatever access or details the job needs, I investigate and do the work, and you confirm it's resolved before we call it done.
Frequently Asked Questions
- What does pm.max_children actually control?
- It sets the maximum number of simultaneous PHP-FPM worker processes — set too low, requests queue under load; set too high without enough RAM, the server can run out of memory.
- Why is my site slow even though the server has CPU to spare?
- If PHP-FPM has run out of available worker processes, incoming requests queue up waiting for one to free up, even while CPU sits mostly idle — it's a configuration limit, not a hardware one.
- What's the difference between dynamic, static and ondemand PHP-FPM modes?
- Dynamic scales worker count up and down within limits based on demand; static keeps a fixed number always running; ondemand starts workers only when needed, minimising idle resource use on low-traffic sites.
- How do I know how much memory each PHP-FPM process uses?
- Checking real-world memory usage per worker (via tools like ps or a monitoring dashboard) under actual application load gives a realistic figure to calculate pool sizing from.
- Can too many PHP-FPM workers crash my server?
- Yes, if pm.max_children is set higher than the server's RAM can actually support, simultaneous busy workers can exhaust available memory and cause broader instability.
- Does PHP-FPM tuning help WordPress specifically?
- Yes, WordPress sites under real traffic are a very common case where default PHP-FPM settings cause slowdowns or 502/504 errors that proper pool tuning resolves.