Creating a separate PHP-FPM pool isolates one site or application from other PHP workloads that share the same master process. A dedicated pool can run under its own Unix user, expose its own socket or TCP listener, and keep request limits or logging choices separate from the default pool.
A pool is a named configuration section loaded by PHP-FPM when the main php-fpm.conf file includes the pool directory. Each pool needs a unique listen endpoint plus a valid process-manager definition, and php-fpm -tt resolves those values before a reload so configuration problems can be caught before traffic is pointed at the new backend.
Examples below use the common Ubuntu or Debian layout under
/etc/php/8.3/fpm/pool.d/
, but the same pool structure applies on other Linux packages with different paths and unit names. When a Unix socket is used, keep the socket path short and make its ownership or mode match the web-server account, otherwise PHP-FPM or the web server can fail before the new pool accepts requests.
Related: How to enable the PHP-FPM status page
Related: How to enable the PHP-FPM slow log
$ ls /etc/php/8.3/fpm/pool.d/*.conf /etc/php/8.3/fpm/pool.d/www.conf $ grep -H '^listen = ' /etc/php/8.3/fpm/pool.d/*.conf /etc/php/8.3/fpm/pool.d/www.conf:listen = /run/php/php8.3-fpm.sock
Ubuntu and Debian packages commonly store pool files under /etc/php/<version>/fpm/pool.d. Fedora, Red Hat, and CentOS Stream usually use /etc/php-fpm.d instead, so reuse the active package layout instead of mixing paths from another distribution.
$ sudo vi /etc/php/8.3/fpm/pool.d/billing.conf
Keep the filename and the pool name aligned with the application so later status checks, log paths, and listener targets stay easy to recognize.
Related: How to find PHP configuration files
[billing] user = billing group = billing listen = /run/php/billing.sock listen.owner = www-data listen.group = www-data listen.mode = 0660 pm = ondemand pm.max_children = 10 pm.process_idle_timeout = 10s
The PHP manual marks listen, user, pm, and pm.max_children as mandatory pool directives. The ondemand example above also uses pm.process_idle_timeout, while pm = dynamic requires pm.start_servers, pm.min_spare_servers, and pm.max_spare_servers as well.
Keep Unix-socket paths short. If the full socket path becomes too long, PHP-FPM can fail to bind the listener even when the pool syntax is otherwise valid.
$ sudo php-fpm8.3 -tt [26-Mar-2026 10:13:13] NOTICE: [billing] [26-Mar-2026 10:13:13] NOTICE: user = billing [26-Mar-2026 10:13:13] NOTICE: listen = /run/php/billing.sock [26-Mar-2026 10:13:13] NOTICE: pm = ondemand [26-Mar-2026 10:13:13] NOTICE: pm.max_children = 10 [26-Mar-2026 10:13:13] NOTICE: pm.process_idle_timeout = 10 [... resolved pool settings omitted ...] [26-Mar-2026 10:13:13] NOTICE: configuration file /etc/php/8.3/fpm/php-fpm.conf test is successful
Use the binary that matches the installed PHP branch, such as php-fpm8.4 on a newer Ubuntu or Debian host. RHEL-family packages commonly use the unversioned php-fpm -tt command.
Do not reload the service until the configuration test is successful.
$ sudo systemctl reload php8.3-fpm
Replace php8.3-fpm with the installed unit name when the host uses another PHP branch or the unversioned php-fpm service.
$ ls -l /run/php/billing.sock srw-rw---- 1 www-data www-data 0 Mar 26 10:13 /run/php/billing.sock
If the pool listens on a TCP address instead of a Unix socket, verify the bound endpoint with ss -ltn instead of checking /run/php.
The new pool stays unused until the web server or reverse proxy is pointed at this listener, so update that upstream target separately if requests still land on the default pool.