3 min read

PHP-FPM Tuning Explained Simply for Small and Medium Projects

A practical explanation of PHP-FPM tuning for small and medium projects, including pm settings, memory usage, worker counts, and what really matters.

If you want the short answer, most small and medium projects do not need aggressive PHP-FPM tuning. They need sane defaults, enough memory, and a process manager setting that matches the traffic pattern.

The goal is not to create the most advanced config on the internet. The goal is to stop wasting RAM, avoid queueing requests, and keep the app responsive.

What PHP-FPM actually does

PHP-FPM manages worker processes that execute PHP requests. When traffic comes in through Nginx, PHP-FPM decides which worker handles the request and how many workers should exist.

That means most tuning decisions come down to three things:

  • How much RAM your server has
  • How heavy each PHP request is
  • Whether your traffic is steady or bursty

The three process manager modes

  • pm = static: fixed number of workers, predictable but less flexible
  • pm = dynamic: keeps a baseline and grows under load
  • pm = ondemand: spawns workers only when needed, often good for low traffic

Which mode should you use?

For most small servers and low-traffic apps, ondemand is a good default because it saves memory. For medium projects with more regular traffic, dynamic is usually the safer choice.

A practical small-project config

For a VPS with limited RAM and modest traffic, this is a simple starting point:

pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s
pm.max_requests = 300

This keeps memory usage under control and helps recycle workers before memory growth becomes a real problem.

A practical medium-project config

For a project with more stable traffic, try:

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500

This is not magic. It is just a strong baseline you can adjust after observing real usage.

How to calculate pm.max_children

This is the setting that matters most. A practical method is:

  1. Measure roughly how much memory one PHP worker uses.
  2. Keep enough RAM free for Nginx, MySQL, the OS, and cache.
  3. Divide the remaining RAM by worker memory usage.

If one worker uses about 60MB and you can safely dedicate 600MB to PHP-FPM, then pm.max_children = 10 is a reasonable starting point.

Settings people overthink too much

Most small and medium teams spend too much time debating tiny values while ignoring the real bottlenecks like slow SQL queries, no caching, or heavy plugins.

Focus first on:

  • pm
  • pm.max_children
  • pm.max_requests
  • server memory usage

Where to edit PHP-FPM settings

On Ubuntu, pool configs are often here:

/etc/php/8.3/fpm/pool.d/www.conf

After changes:

sudo systemctl restart php8.3-fpm

How to know if your settings are wrong

  • Frequent 502 errors under load
  • Requests are slow even when CPU is not maxed out
  • Memory pressure or swapping
  • PHP-FPM logs mention worker exhaustion

Common mistakes

  • Setting pm.max_children too high and exhausting RAM
  • Copying enterprise configs onto a tiny VPS
  • Changing 10 settings at once and not measuring anything
  • Ignoring MySQL and application bottlenecks

Useful next reads

If PHP-FPM is already failing, read How to Fix 502 Bad Gateway with Nginx and PHP-FPM. If you are deploying from scratch, read How to Deploy a PHP App on Ubuntu Step by Step in 2026.

Quick FAQ

Should I always use ondemand?

No. It is great for low traffic, but dynamic often feels better for steadier workloads.

Does PHP-FPM tuning matter more than app optimization?

No. Good tuning helps, but bad queries and heavy code usually hurt more.

How often should I retune PHP-FPM?

After major traffic changes, app changes, or server upgrades.

Linux Mar 28, 2026