# Nginx and PHP-FPM Together: Sockets, Pools, fastcgi_params

> How to connect Nginx to PHP-FPM via a socket or TCP, tune a pool and fastcgi_params so a PHP site survives traffic spikes.

## How Nginx passes requests to PHP-FPM

Nginx cannot execute PHP itself — it serves static files and proxies dynamic requests to a separate PHP-FPM (FastCGI Process Manager) process over the FastCGI protocol. This is handled by the `fastcgi_pass` directive inside a `location` block that matches files with a `.php` extension. PHP-FPM runs the script and sends the result back through the same channel.

The link between Nginx and PHP-FPM can be built two ways: through a Unix socket or through a TCP address such as 127.0.0.1:9000. On a single server a socket is usually faster and does not occupy a port, while TCP is convenient when PHP-FPM runs in a separate container or on another machine. On ZevsHost.net shared hosting and VDS with cPanel and ISPmanager 6, a socket is used more often — the panel creates one automatically for every user.

## Configuring the location for .php files

The basic block for a PHP site looks like this — a regex match, passing the socket, and a mandatory `SCRIPT_FILENAME`.

```
location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
```

Without `SCRIPT_FILENAME`, PHP-FPM has no idea which file to run and returns a blank page or a "No input file specified" error. The `fastcgi_params` file usually lives in `/etc/nginx/` and is loaded with the `include` directive — there is no need to rewrite it entirely, just add the missing parameters on top.

## Socket or TCP: how to choose without dropping connections

The difference between the two connection methods lies in speed and in limits on the number of simultaneous connections.

| Method | Example address | When to use it |
| --- | --- | --- |
| Unix socket | unix:/run/php/php8.3-fpm.sock | Nginx and PHP-FPM on the same server |
| TCP localhost | 127.0.0.1:9000 | PHP-FPM in a container, needs an explicit port |
| TCP over the network | 10.0.0.5:9000 | PHP-FPM moved to a separate server |

If Nginx logs show the error `connect() to unix:/run/php/php8.3-fpm.sock failed (11: Resource temporarily unavailable)`, the socket queue is full: the PHP-FPM pool cannot process requests fast enough. The fix is to raise `listen.backlog` in the pool or increase the number of worker processes.

## Tuning a PHP-FPM pool for load

A pool is described in a file such as `/etc/php/8.3/fpm/pool.d/www.conf`. Three parameters control how many requests PHP-FPM handles at once.

```
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
```

`pm.max_children` is a hard cap on worker processes. It is calculated as: available memory minus memory for the system and Nginx, divided by the average size of one PHP process (usually 40-80 MB for a CMS like WordPress). Set it too high and the server swaps under peak load; set it too low and Nginx starts returning 502 on a traffic spike.

## Diagnostics: where to look when the site will not open

The check order for a 502 or 504 error on a PHP-FPM site:

- Service status: `systemctl status php8.3-fpm`.
- The socket path in the pool config matches the path in `fastcgi_pass`.
- The PHP-FPM log in `/var/log/php8.3-fpm.log` for "max\_children reached".
- The Nginx log in `/var/log/nginx/error.log` for "upstream timed out".

A detailed breakdown of specific 502 and 504 error codes with commands for each case is covered in a separate article on [502 and 504 diagnostics](https://www.zevshost.net/en/kb/nginx-502-504-diagnostika/). General rules on which location wins for .php files are covered in the article on [location priority](https://www.zevshost.net/en/kb/nginx-location-prioritet/).

## Summary: checklist for the Nginx and PHP-FPM link

- The socket path or TCP address in `fastcgi_pass` matches `listen` in the PHP-FPM pool.
- The `SCRIPT_FILENAME` parameter is set explicitly, not inherited from an old config template.
- `pm.max_children` is calculated from the server's RAM, not left at the default.
- After editing configs, `nginx -t` and `systemctl reload php8.3-fpm` were both run.
- The link matches the PHP version actually installed on the server — check with the [article on installing Nginx](https://www.zevshost.net/en/kb/nginx-ustanovka-ubuntu-debian/) and the output of `php -v`.

---

Source: https://www.zevshost.net/en/kb/nginx-php-fpm-svyazka/
