30 October 2018
PHP-PM guide: Getting started with the process manager
PHP Process Manager is a relatively new way of running PHP applications. In this article, you’ll find out what it is, how to run it and if it’s better than the other currently available server solutions.
What is PHP Process Manager?
According to its creators, PHP Process Manager (PHP-PM/PPM) is “a process manager, supercharger and a load balancer for PHP applications”. The main features of PHP-PM are:
- a performance boost – up to 15x (compared to PHP-FPM, and Symfony applications),
- integrated load balancer,
- hot-code reload (when PHP files change),
- static file serving for easy development procedures,
- support for HttpKernel (Symfony/Laravel), Drupal (experimental), and Zend (experimental).
PHP Process Manager uses ReactPHP and Symfony components. It also requires PHP-cgi and PCNTL – the PHP library to manage processes. Probably in the future, there will be support for Swoole (an asynchronous library for PHP written in C). Take a look at the dedicated issue in the PHP-PM repository for more details.
How does PHP-PM work?
First, take a look at the image below.
This is a standard pipeline of a PHP request. In the beginning, a request is sent. Some “front” on the server side (nginx, Apache, etc) handles the request and runs the PHP script. PHP does its job, then simply dies. This method of handling PHP requests has been used for years. It has some advantages, like virtually no problems with memory leaks.
Then, there’s the PHP-PM way.
When the server starts, workers are created – they bootstrap your application. Then, nginx, if used, will forward the request to PPM. Alternatively, PHP-PM itself handles the request and load-balances traffic to workers. Contrary to the method above, workers don’t die after serving each request. But they are restarted from time to time or when they have handled a certain number of requests (the default is set to 10000). Restarts are the simplest way to handle PHP memory leaks.
What to use PHP-PM with?
So far, PHP Process Manager looks promising. But what else do you need?
First of all, PHP-PM requires Request-Response PSR-7 abstraction from your application. There’s a HttpKernel adapter for Symfony and Laravel, which should work stable. There are also bridges for Zend, CakePHP and Drupal, but, according to the documentation, they’re in the beta phase. For that reason, it wouldn’t be wise to use them in development.
How to run PHP Process Manager?
You can run PHP-PM in many ways, e.g. by using a prepared docker image or building the image yourself. Of course, you can also set it up manually on your machine.
Let’s start with docker. There are already three ready-to-use images for PHP-PM. The first one is nginx as a proxy + PHP-PM. The second one is PHP-PM standalone, and the third one PHP-PM as binary. The creators suggest using nginx + PHP-PM as it’s the fastest one.
But you have to remember that if you want to run PPM on a local machine or server, you can do it only on UNIX systems due to the PCNTL restrictions.
If you want to learn how to implement each method, there’s quite a comprehensive description in the documentation.
Whale, whale, whale... what have we here?
Is PHP Process Manager the best server solution?
Of course, the most important question is whether PHP-PM is the most effective solution. In order to find out, I’ve compared nginx + PHP-PM, nginx + FPM and an Apache server, using Symfony and Laravel Frameworks. In each test, I was using:
- 4 cores processor,
- 24 GB memory,
- docker containers on Linux alpine with the same PHP base (7.2); the only difference was the setup of PPM, FPM and Apache,
- most tests were run at 1-minute intervals,
- siege for tests (with benchmark flag),
- PHP Process Manager with 8 workers and a disabled debug mode,
- Symfony running in the production environment,
- Laravel running without the debug mode.
I was increasing concurrency to simulate more users. I focused on the speed and stability of all three server solutions.
Results
The first thing worth noticing is that PHP-PM consumed a lot more memory on standby (83MB) than FPM (13MB) and Apache (8MB).
During the first test, I was using Symfony 4.1. I created a simple Symfony skeleton app. Let’s take a look at its performance:
As you can see, PHP Process Manager is over 5 times faster, as long as it handles a single request. When the load is increased, it loses its advantage. That being said, PHP-PM is still over 2 times faster than the other 2 solutions.
The second test was more challenging. I added an API platform framework to the skeleton from the previous test and created a simple entity. My endpoint was returning 100 serialized objects from the database. Let’s take a look at the chart:
PHP Process Manager is still faster than FPM and Apache.
After that, I tested a Laravel application. Same as with the Symfony test, I built just a simple skeleton app in version 5.6 – a Hello World app in Laravel:
As you can see, the results are rather random. This probably happened because not enough time was spent to bootstrap the framework (read cache, etc.).
The next test was run on the Laravel example in version 5.5. Here’s how it turned out:
Once again, the results look random. PHP Process Manager works faster with 100 concurrent requests, but, in other cases, there’s not much difference.
In the end, I wanted to test the stability of PHP-PM. So, I decided to run a 10-hour test on the simplest endpoint of a Symfony application. Here’s the result:
PHP-PM is still the fastest option and it isn’t a surprise. What surprised me though was old Apache beating FPM. Another thing I should mention is that PHP-PM returned 3 bad requests (its rivals didn’t have bad requests at all).
Can’t be denied that PHP Process Manager has a huge potential
These are the conclusions I drew after I ran all the tests:
- in almost all cases, all servers remained stable; only in the 10-hour run, PHP Process Manager lost three requests,
- in the other tests I ran, PHP-PM lost even more requests;
- PHP-PM could cause big memory leaks (there’s probably some issue with restarting workers); it consumed all of my memory and crashed my PC; it happened twice,
- I never got the promised,15x better performance (+/- 5x was all I got),
- there were times when PHP-PM “lost” some requests; on the whole, there were just a couple, but I should emphasize that Apache and FPM didn’t lose a single one.
In the future, we may get Swoole support, which will provide more stability and speed. But the big question is if PHP-PM is ready for production right now? I think I’ll let you answer that one yourself.