We had already attended Kevin Dunglas' FrankenPHP conference at SymfonyCon Disneyland Paris 2022, and were able to take advantage of a second conference addressed at DrupalCamp Rennes 2024.
While interesting and promising, the project was still in its infancy, and we couldn't imagine offering a solution with so little feedback as a replacement for our customers' tried-and-tested stack.
What is FrankenPHP?
FrankenPHP is a PHP application server written in Go. It is based on the Caddy and offers a number of features, the main ones being :
- Enhanced performance
- Production-quality server
- Create self-contained, self-executing binaries
- Easy configuration
- Offer current functionalities not covered by current systems (103 Early hints, Real Time, etc.)
What about FrankenPHP with Drupal?
Launched in 2022, the github repository for configuring a FrankenPHP with Drupal was refined following the DrupalCamp in Rennes.
Good news, it works! You can now effortlessly run Drupal with FrankenPHP.
And what about performance?
Edit 04/04/2024 : Corrections following refinement of tests.
The tests were carried out from and on a development workstation using Docker. The figures are therefore to be taken for what they are, and are only intended to give an order of magnitude of the differences between our usual stack and frankenPHP.
- Tests performed using the Docker-Jmeter docker image
- Usual stack: A PHP-FPM container + Nginx
- FrankenPHP stack: One FrankenPHP container
During testing, only the containers in the stack to be tested are switched on.
For testing purposes, we have installed a Drupal with the Umami sample profile on each of the stacks, and are looking for the "Vegan" string on perf tests for 600 seconds with an HTTP call (no HTTPS), a single thread and no delay. The database used in both cases is a MariaDB database located in a container of the respective stacks.
Tests were run 2 times to ensure consistency.
Tests were run as an anonymous user with caches enabled and without caches.
The configuration is as follows for tests with caches deactivated in order to use more computing power:
Configuration of settings.nocache.php included in settings.php :
$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['page'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
$settings['container_yamls'][] = $app_root . '/sites/default/services.nocache.yml';
Configuration of services.nocache.yml :
parameters:
twig.config:
cache: false
services:
cache.backend.null:
class: Drupal\Core\Cache\NullBackendFactory
Testing with the PHP-FPM stack
Let's start with the stack we usually use, namely a PHP-FPM container including a NGINX configured and optimized for Drupal.
Anonymous, with caches disabled
The result is :
- Number of calls: 480
- Minimum response time: 181ms
- Maximum response time: 282ms
- Average response time: 202.22ms
Anonymous, with caches enabled
The result is :
- Number of calls: 569
- Minimum response time: 3ms
- Maximum response time: 45ms
- Average response time: 5.43ms
Testing with FrankenPHP
As a reminder, we're using FrankenPHP with mariadb (at the time of testing, the github offered postgresql by default, but we'll look at this case later).
Anonymous, with all caches disabled
The result is :
- Number of calls: 471
- Minimum response time: 212ms
- Maximum response time: 329ms
- Average response time: 226.18ms
Anonymous, with all caches enabled
The result is :
- Number of calls: 568
- Minimum response time: 4ms
- Maximum response time: 32ms
- Average response time: 6.36ms
Comparison of results
NGINX + PHP-FPM | FrankenPHP | |
Number of calls | 480 | 471 |
Min. time in ms | 181 | 212 |
Max. time in ms | 282 | 329 |
Median time in ms | 202.22 | 226.18 |
NGINX + PHP-FPM | FrankenPHP | |
Number of calls | 569 | 568 |
Min. time in ms | 3 | 4 |
Max. time in ms | 45 | 32 |
Median time in ms | 5.43 | 6.36 |
Very tight differences between the 2, but slight improvement for NGINX + PHP-FPM, mitigated by the fact that the configuration of this stack has been better optimized and tested than FrankenPHP, which is configured by default (no worker mode) and is still in its infancy.
The tests are what they are, which is to say not much: very basic tests, run on the same machine, no specific optimization, use of Drupal caches... But they do show a nice difference between the 2 systems, enough to push the tests with FrankenPHP.
What about postgreSQL?
The first tests were carried out with postgreSQL on FrankenPHP, the default configuration provided on the repo being postgreSQL.
For your information, here are the tests with FrankenPHP only and PostgreSQL.
FrankenPHP + PostgreSQL | FrankenPHP + MariaDB | |
Number of calls | 556 | 565 |
Min. time in ms | 13 | 4 |
Max. time in ms | 51 | 29 |
Median time in ms | 28.64 | 10.01 |
This time we see a difference of x2 to x3 in response time in favor of mariaDB.