PHP-FastCGI Process Manager (or PHP-FPM) is widely used on sites that use WordPress, a hugely popular content management system. PHP-FPM is a processor for PHP, one of the most common scripting languages, that enables WordPress sites to handle a greater volume of web traffic without relying on as many server resources as when using alternative PHP processors.
How does PHP-FPM work? What security does it offer? And how easy is it to set up?
We’ll cover all this and more in this guide to PHP-FPM.
The Structure of PHP-FPM
PHP is a high-level programming language. As a result, PHP scripts need to be compiled before a web server (specifically its underlying processor hardware) can comprehend it.
Generally, web servers use integrated modules to compile PHP scripts, such as Common Gateway Interface (CGI) or single user PHP (suPHP). Web servers leveraging these handlers pair with processing PHP scripts, then compile and execute them as part of their standard processes when responding to traffic. To execute, they use the server process’s ownership and permission configurations. This creates a stable method of using PHP scripts.
But PHP-FPM is designed to fill the gaps in other PHP handlers. The work is handled by a separate service that was created exclusively to process PHP scripts. It’s arranged as a master process handling singular worker processes in pools. Whenever the server gets a PHP script request, it utilizes a proxy, FastCGI connection to pass that request on to the PHP-FPM service.
That service is able to pick up these requests via Unix sockets or on the network ports of the host server. While requests are passed through proxy connections, the PHP-FPM service needs to be running on the same server as the web server. Crucially, the proxy connection used by PHP-FPM is different to the traditional one: because PHP-FPM gets a proxied connection, a PHP-FPM worker that’s available takes the request from the web server.
Then, the script is compiled and executed by PHP-FPM, with the output returned to the web server. The system releases the PHP-FPM worker when it’s done with the request, then awaits further requests.
Worker processes are dynamically made and terminated by the PHP-FPM master process as traffic to scripts rises and falls. This is done within configurable limits. Additional worker processes that are created to manage traffic increases are terminated only once a specific length of time has passed, which enables worker processes to stay available for as long as traffic levels remain at a higher level.
Furthermore, worker processes also terminate and are recreated after completing a set amount of requests, which is important for stopping memory leaks while PHP scripts are processed. Every PHP user may have a separate worker process pool to handle PHP requests. While this can push some of the overhead related to PHP-FPM usage higher, the extra resource expense should be worthwhile considering the benefits.
The architecture of PHP-FPM is similar in some ways with NGINX and Apache web servers, as well as other event-driven examples, with the Event Multi-Processing Module. By using this approach to PHP script processing, you can expect better processing, security, configurability, and stability.
The Performance of PHP-FPM
PHP-FPM offers two main performance advantages: it lets websites handle PHP requests more efficiently and allows for opcode caching.
The event-driven architecture of PHP-FPM enables PHP scripts to utilize whatever available resources on a server they need to, but without the extra overhead caused by running them in web server processes. With PHP-FPM, worker processes may be used and reused over and over, with no need to make and terminate them for each individual PHP request.
While the price of starting and terminating new processes for every request is generally on the small side, the overall cost can rise quickly when the server starts to manage more traffic than usual. PHP-FPM is able to serve higher volumes of traffic than traditional handlers, while allowing for more efficient use of resources.
The biggest benefit in performance comes with PHP-FPM allowing opcode caching. This causes the opcode from compiled scripts to be cached in RAM. If a PHP script request is received, PHP-FPM searches for copies of the script that have already been cached. If it locates one, PHP-FPM executes it with the cached opcode straight away, then carries on processing that request.
As PHP-FPM can execute opcode from memory so quickly, it eliminates the need to read the source code for a script from disk and compile that source code to opcode. Reading data directly from the server’s memory is significantly more efficient than reading it from the server’s filesystem instead.
Additionally, PHP-FPM is more time- and resource-effective because it doesn’t need to compile PHP source code to opcode. As with making and terminating processes, the expense and time for reaching and compiling source code files is generally small individually, but it increases with further occurrences. For instance, systems that repeat these steps potentially thousands of times per second will drive the overall cost up significantly and have a major effect on a web server’s resource usage. By using opcode caching, you can process PHP scripts more efficiently, particularly when handling a high number of PHP script requests.
The Security Capabilities of PHP-FPM
PHP-FPM offers a higher standard of security than other PHP processors, as it allows opcode caching with isolated PHP processing for every user. Opcode caching is ineffective when leveraging CGI and suPHP handlers because of how they handle memory usage. While opcode caching is supported by the DSO handler, the DSO module needs PHP scripts to be run as an Apache user. That can bring security dangers with it.
Furthermore, you may need to allow for extra configuration when using DSO to make sure that scripts have the right permissions to let an Apache user read them correctly. This issue can be fixed, but that typically requires extra server modules to be installed or outdated tech to be used. But PHP-FPM offers opcode caching and isolated script processing as standard.
You need to be careful, though, to set up PHP-FPM for security properly while using opcode caching. For instance, the primary PHP configuration file on the server must have these values set to true:
opcache.validate_root = true
opcache.validate_permission = true
These settings bring an extra layer of protection to stop users from accessing others’ opcode caches. The core PHP-FPM configuration files carry the settings required to use PHP-FPM safely and securely. These concerns largely affect hosting environments with a multi-tenant setup.
The Stability of PHP-FPM
PHP-FPM offers impressive stability, as its architecture stops a server from being overwhelmed by PHP processing. Extra processes need to be made when web servers manage PHP script requests in their own processes. And as PHP script traffic rises, servers can become so swamped with requests that they stop responding.
PHP-FPM is only able to serve the amount of traffic that its worker processes can manage. When it’s set up correctly, PHP-FPM establishes a limit on the number of PHP script requests that it can process simultaneously.
When its worker processes are used to their maximum capabilities, extra PHP script requests will lead to gateway errors or timeouts. Rather than leveraging all of the server resources awaiting a response, the server will deliver a 503 or 504 HTTP status code. Those codes can be frustrating for visitors, but they’re better than letting a hosting server stop responding altogether. Furthermore, website owners can set up bespoke 503 status pages to provide a stronger user experience, instead of relying on generic error pages.
While PHP-FPM offers stable performance because of its architecture, it can turn into a bottleneck for script processing if configured in the wrong way. Setting it up right is essential to ensure it offers an adequate number of workers for processing the traffic volume that the server can safely process.
If there aren’t enough workers, an extreme number of 503 or 504 responses may be delivered, even when the server is seeing normal traffic levels. This issue is more frequent when single-tenant servers are using PHP-FPM with one pool of worker processes across all sites (e.g. a VPS hosting server). But hosting environments with a multi-tenant approach and separate worker process pools should have a PHP-FPM that’s configured correctly to provide the right amount of workers for all tenants’ traffic requirements.
The Configurability of PHP-FPM
PHP-FPM offers a bigger range of configuration options than alternative PHP processors. Lots of these options may be defined in a different way for each site on a server. Some of those configuration options are worker limits, status reports, and worker creation behavior.
You can tweak PHP-FPM to achieve the highest standard of performance for PHP website hosting, improving on other PHP handlers that don’t include these configuration options. However, configuring PHP-FPM in the right way can be fairly complicated and time-consuming, so you may need an experienced systems administrator to help you get started.