How Linux Handles PHP-FPM for Web Content
This article explains how the Linux operating system manages the PHP FastCGI Process Manager (PHP-FPM) daemon to serve dynamic web pages. It details the interaction between the Linux kernel, system service managers, and web servers like Nginx or Apache. You will learn about process lifecycle management, inter-process communication via sockets, pool execution models, and Linux-level resource allocation.
Process Initialization via systemd
In modern Linux distributions, PHP-FPM is managed as a background
daemon by systemd. When the operating system boots or the
service is manually started, systemd reads the unit
configuration file (typically located at
/lib/systemd/system/php-fpm.service) and executes the
primary PHP-FPM binary.
The initial process launched is the Master Process, which typically runs with root privileges. Running as root allows the master process to open privileged network ports, bind to restricted Unix domain sockets, and allocate shared memory regions before creating less-privileged child processes.
Master and Worker Architecture
Linux handles PHP-FPM workloads using a master-worker process model:
- Master Process: Does not execute PHP code directly.
Its role is managing the worker processes, reading configuration files,
handling operating system signals (such as
SIGHUPfor graceful reloads andSIGTERMfor shutdown), and creating or destroying workers based on traffic demand. - Worker Processes: The master process uses the Linux
fork()system call to spawn child worker processes. Immediately after forking, these workers drop root privileges and switch to an unprivileged system user (such aswww-dataornobody). Workers are responsible for parsing, compiling (via OPcache), and executing dynamic PHP scripts.
Inter-Process Communication (IPC)
The Linux kernel acts as the transport layer between the upstream web server (such as Nginx or Apache) and the PHP-FPM workers. When a request for a dynamic file is received, the web server passes it to PHP-FPM using one of two methods:
- Unix Domain Sockets: A file-based communication
channel (e.g.,
/run/php/php-fpm.sock) residing entirely within the Linux Virtual File System (VFS). Unix sockets avoid network protocol overhead, bypassing the TCP/IP stack, checksums, and packet wrapping. This method is preferred when the web server and PHP-FPM run on the same Linux host due to reduced CPU overhead and lower latency. - TCP/IP Sockets: Network-based sockets bound to an
IP address and port (e.g.,
127.0.0.1:9000). This routing utilizes the Linux loopback network interface. While it incurs slight protocol overhead, it allows the web server and PHP-FPM daemon to run on completely separate Linux instances.
Process Management Modes
The Linux kernel schedules worker processes according to the configuration defined in the PHP-FPM pool configuration files. PHP-FPM supports three execution modes that dictate how Linux handles process creation:
- Static: A fixed number of worker processes are
created at startup. The Linux kernel maintains these processes in
memory, eliminating the overhead of frequent
fork()operations under high, sustained traffic. - Dynamic: The master process dynamically creates and
removes workers based on incoming demand, guided by directives such as
pm.min_spare_serversandpm.max_children. The kernel allocates and frees memory as workers scale up and down. - Ondemand: No workers are initialized at startup.
Workers are spawned exclusively when incoming connections hit the socket
and are killed by the master process after an idle timeout period
(
pm.process_idle_timeout), conserving Linux RAM during low traffic.
Kernel Resource Allocation and Scheduling
When an HTTP request is forwarded through the socket, the Linux kernel's Completely Fair Scheduler (CFS) allocates CPU time slices to the assigned PHP-FPM worker process.
Linux manages these processes using standard kernel-level safeguards:
- Memory Management: Each worker maps required shared
libraries and OPcache shared memory into its address space. If a worker
exceeds limits set by
memory_limit, the script halts. If the entire system exhausts physical memory, the Linux Out-Of-Memory (OOM) killer uses theoom_scoreto determine whether to terminate rogue PHP-FPM worker processes to protect the kernel. - File Descriptors: Every socket connection, log
file, and open PHP script requires a file descriptor. The Linux kernel
tracks these using system-level (
fs.file-max) and user-level (ulimit -n) limits to prevent resource exhaustion. - Signal Handling: When dynamic content finishes executing, the worker flushes standard output back through the socket to the web server and signals the kernel that it is ready for the next FastCGI connection.