Forest header image

Symfony Finland
Random things on PHP, Symfony and web development

Symfony Benchmarks: PHP-FPM vs. PHP-PM (on PHP 7 and HHVM)

In the previous articles we have evaluated PHP performance on different runtimes, adding server resources (CPU & RAM), and comparing the Symfony Proxy and Varnish - using eZ Platform - a CMS built on the Symfony Framework.

Now let's try an unconventional method of executing PHP applications, PHP-PM.

PHP became popular partly due to the fact that it's very easy and safe to run. Upon each request the PHP starts from scratch, bootstraps the application, sends the response and dies.

PHP developers don't need to worry about the complexities of a long living application with memory leaks, but the continuous repetition of the same basic tasks does have an effect on performance. Opcaching helps improve performance, but there is still a lot of work done for "nothing".

Close to two years ago, in February 2014, an alternative way of running PHP was introduced: Bring High Performance Into Your PHP App (with ReactPHP). After first causing some waves in the PHP community, it faded into the background.

But it did lead directly to PHP-PM and probably influenced the creation of PHPFastCGI. Both run PHP as a continuous process that responds to requests, making it possible to remove routine bootstrapping out of the equation.

This brings increased performance, but makes the application more vulnerable to developer mistakes and memory leaks due to the longer lifecycle. This is why the method is still considered experimental, but thought by some as being the future of executing PHP.

PHP-PM supports Symfony Framework applications by default and eZ Platform as one worked as expected, right out of the box. So it's worth a round of tests to see how it holds up in a real world application.

PHP-PM vs. PHP-FPM Performance

Inline with the previous tests I ran requests against the eZ Platform Demo installation. The traditional PHP-FPM setup was running on PHP 7.0.1. PHP-PM was behind Nginx as a load balancer and both HHVM 3.11 and PHP 7.0.1 were tested.

Process counts for PHP-PM were set at double to the CPU core count, PHP-FPM had a max_child limit of 10 - Try free trial for high performance VPS on UpCloud. Request concurrency was set at 10. Tests were ran against the Front Page and the REST API calls, without Symfony Proxy or other high level caching. Tests were repeated three times and average results are reported.

Front Page with Symfony Proxy and Varnish
Front Page without Symfony Proxy

For the complete page rendering PHP-PM displays a significant advantage to the traditional PHP-FPM setup. PHP-FPM remains in the same ballpark with PHP-PM. HHVM is consistently more performant than the PHP 7 counterpart.

Front Page with Symfony Proxy and Varnish
API without Symfony Proxy

For the API calls PHP-PM runs yield significantly higher results than the PHP-FPM setup, indicating that a larger percentage of time in these is spent bootsrapping while processing is minimal. HHVM starts out on top and after a tie at 2 CPUs, PHP 7 provides higher returns with the 4 and 8 CPU setups.

Comparing PHP-FPM, PHP-PM, Symfony Proxy and Varnish

To put the numbers into a larger perspective with cached results they are compared with results for the Symfony Proxied results (ran with PHP-FPM) and Varnish.

Front Page with Symfony Proxy and Varnish
Full Frontpage

For full page loads both the Symfony PHP Reverse Proxy and Varnish trounce any dynamically generated page loads. With a good caching strategy and merging fragments with ESI on proxy level and a PHP-FPM backend will likely yield best real-world results.

Front Page with Symfony Proxy and Varnish
REST API Call

For REST API calls with limited processing PHP-PM with PHP 7 inches closer to Symfony Proxy performance. While the PHP proxy is still twice as fast, it's worth considering that for hard-to-cache-and-purge requests a fast-enough dynamic backend might be the practical option.

Conclusions

Running long living PHP processes remains a curiosity, but results offer a promise of significantly improved performance when time spent bootstrapping the application is relatively long compared to the total length of the processing.

An example is a continuosly running daemon in the currently fashionable world of tiny API calls. Behind the scenes they might become a cascade over a long chain, e.g. a service calls on a REST API that calls a REST API that calls a REST API that calls a REST API that calls a REST API...

Unfortunately PHP-PM is not yet a practical solution for running production services as both PHP 7 and HHVM end up crashing from time to time. Coming from a pure gut feeling HHVM seems to be a bit more stable out of the pair with PHP-PM.

Should a robust application server of sorts arise it has the potential of running modern (PSR7, HTTPKernel...) applications reliably by the mainstream. For more information, read the slides on Breaking Boundaries with FastCGI or see this presentation:


Written by Jani Tarvainen on Friday January 1, 2016
Permalink - Tags: php, php-pm, hhvm, symfony, benchmark

« Symfony Benchmarks: PHP 5.6, HHVM 3.11 and PHP 7.0.1 - Symfony Benchmarks: Symfony Proxy vs. Varnish »