A couple days ago AlexMax commented in CakePHP's IRC channel about the https://github.com/php-pm/php-pm project and it rang a bell for us. We did a couple tests internally and found this could be a great companion to our API plugin, so we wrote a new Bridge for CakePHP and ran some benchmarks.
- https://github.com/php-pm/php-pm is a process manager, supercharger and load balancer for PHP applications. You can also read more about this approach here http://marcjschmidt.de/blog/2014/02/08/php-high-performance.html
- https://github.com/CakeDC/cakephp-phppm is a bridge between PMPPM and CakePHP
- https://github.com/CakeDC/cakephp-api is a full featured API plugin for CakePHP
We put all together and created a sample application (1 posts table with 30 records) to do some benchmarks.
We are not aiming to provide detailed or production figures, just a reference of the results obtained for your comparison. Results are generated from a development box, using PHP 7.1.12-3+ubuntu16.04.1+deb.sury.org+1 with xdebug enabled on ubuntu xenial, 8x Intel(R) Core(TM) i7-4771 CPU @ 3.50GHz
We baked the application using the latest CakePHP 3.5.10, and set application debug to false, and log output to syslog.
As we are interested in boosting API response times the most, we tested the following scenarios
- A) CakePHP json output, served from nginx+phpfpm
- B) CakePHP + API Plugin Middleware integration json output, served from nginx+phpfpm
- C) CakePHP + API Plugin Middleware integration json output, served from php-pm
Benchmark figures were obtained using
ab -n 5000 -c 100 URL
|A) CakePHP json output, served from nginx+phpfpm using php7.1||372.97 [#/sec] (mean)||268.120 [ms] (mean)|
|B) CakePHP + API Plugin Middleware integration json output, served from nginx+phpfpm using php7.1||399.79 [#/sec] (mean)||250.133 [ms] (mean)|
|C) CakePHP + API Plugin Middleware integration json output, served from php-pm using php7.1||911.95 [#/sec] (mean)||109.656 [ms] (mean)|
|D) CakePHP + API Plugin Middleware integration json output, served from php-pm using php7.2||1811.66 [#/sec] (mean)||55.198 [ms] (mean)|
These results for a NOT OPTIMIZED CakePHP application are promising, and the improvement using PHP-PM is huge in this case. There are some important considerations though:
- PHP-FPM is mature and stable, PHP-PM is still in early development, although there is a 1.0 version released already.
- Processes need monitoring, specially regarding memory leaks, we would need to manage a restart policy and be able to hot-restart individual workers
- System integration, init scripts are not provided, even if this is something easy to manage nowadays via systemd or monit, would be good to have for production
- Application bootstrapping should not be affected by the request. If your application bootstrapping depends on the request params, or logged in user, you'll need to refactor your code
- Session handling was not tested, issues are reported for PHP-PM for other frameworks. We were aiming to stateless API's so we don't know if this would be an issue for a regular application
Performance is always a concern for the API developer, applying proven paradigms like the event driven development (https://reactphp.org/) to your existing code would be the way to go and ensure backend frameworks like CakePHP will perform as required when dealing with the peaks we all love and hate.
Edit: We've added a php7.2 based benchmark, with a huge performance improvement.
Giving back to the community
This Plugin's development has been sponsored by the Cake Development Corporation. Contact us if you are interested in:
- Professional, commercial CakePHP development and CakePHP consulting
- Professional CakePHP training
- CakePHP code review