How to Calculate PHP-FPM pm.max_children Correctly (Step-by-Step)

Learn how to calculate the correct PHP-FPM pm.max_children value using real server memory data to prevent 504 Gateway Timeout errors on VPS servers.

If your VPS logs show “server reached pm.max_children setting”, this tutorial will show you how to calculate the correct value safely using actual memory usage from your server.

Table of Contents

Find the PHP-FPM Pool Used by the Website

Before tuning anything, you must identify which PHP-FPM pool the site is using.

The easiest way is to inspect the Nginx configuration for the site.

Run:

				
					nginx -T | grep -n "example.com"
				
			

Example output:

				
					configuration file /etc/nginx/sites-available/example.com.conf:
fastcgi_pass unix:/var/run/example.com.sock;
				
			

This shows that the site is using the PHP-FPM socket:

				
					/var/run/example.com.sock
				
			

The pool configuration will typically be located at:

				
					/etc/php/8.3/fpm/pool.d/example.com.conf
				
			

Check Available Server Memory

Next, determine how much memory is available on the server.

Run:

				
					free -m
				
			

Example output:

				
					Mem: 32094 total
				
			

This VPS has about 32 GB of RAM available. However, you should never allocate all of it to PHP workers.

Other services also require memory:

Service Typical Memory Usage
Operating system + cache 2-4 GB
MySQL / MariaDB 4-6 GB
Nginx <1 GB
Other PHP pools ~1 GB

So a safe PHP-FPM memory budget for this pool might be:

3 GB – 4 GB

Measure Memory Usage of PHP Workers

Next, determine how much memory each PHP worker consumes.

Run:

				
					ps -eo pid,user,rss,args | grep "php-fpm: pool example.com" | grep -v grep
				
			

Example output:

php-fpm-3

The RSS column shows memory usage in kilobytes.

Convert to megabytes:

185000 KB ≈ 180 MB

So each worker consumes approximately:

~180 MB

Calculate the Correct pm.max_children

Now we can calculate the safe pool size.

Formula:

max_children = memory_budget / memory_per_worker

Example:

Memory budget = 3 GB = 3072 MB
Worker memory = 180 MB

Calculation:

3072 / 180 ≈ 17

Safe configuration:

pm.max_children = 16

This allows up to 16 concurrent PHP workers without exhausting server memory.

Update PHP-FPM Pool Configuration

Edit the pool configuration file:

				
					nano /etc/php/8.3/fpm/pool.d/example.com.conf
				
			

Example configuration:

				
					pm = dynamic

pm.max_children = 16
pm.start_servers = 4
pm.min_spare_servers = 3
pm.max_spare_servers = 8

pm.max_requests = 500
				
			

Restart PHP-FPM:

				
					php-fpm8.3 -t
systemctl restart php8.3-fpm
				
			

Monitor the Pool After Changes

After adjusting the pool, monitor the logs to ensure the limit is no longer reached.

Check PHP-FPM logs:

				
					grep -i max_children /var/log/php8.3-fpm.log
				
			

Example warning before tuning:

server reached pm.max_children setting (6), consider raising it

If these warnings disappear, the pool size is now correctly tuned.

You should also monitor Nginx error logs for upstream timeouts:

				
					grep "upstream timed out" /var/log/nginx/error.log
				
			

Important Notes

Increasing pm.max_children does not fix slow application code.

If PHP requests are slow (heavy Laravel queries, inefficient database calls, etc.), workers remain busy longer and the pool will still saturate.

Proper tuning simply ensures the server has enough workers to handle traffic bursts safely.

Summary

Instead of guessing pm.max_children, calculate it using real data:

  1. Identify the PHP-FPM pool used by the site

  2. Check available server memory

  3. Measure memory usage of PHP workers

  4. Allocate a safe PHP memory budget

  5. Calculate the pool size using the formula

This method prevents both:

Tharindu

Hey!! I'm Tharindu. I'm from Sri Lanka. I'm a part time freelancer and this is my blog where I write about everything I think might be useful to readers. If you read a tutorial here and want to hire me, contact me here.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button