Docs

Choosing a variation

BenchKit ships the same application on three web servers and every PHP version it supports. The image tag picks both.

BenchKit publishes one application in several image variations, each serving PHP with a different web server, on every PHP version the application supports. The application is identical in all of them, so any difference between two runs comes from the server or the PHP version rather than from the code. The tag you pull decides what you get.

Images are published to Docker Hub at serversideup/benchkit-laravel and to the GitHub Container Registry.

At a glance

VariationHow PHP is servedTag
FPM-NGINXnginx hands PHP requests to PHP-FPMlatest
FrankenPHPOne binary serves PHP directlyfrankenphp
FPM-ApacheApache hands PHP requests to PHP-FPMfpm-apache

All three listen on port 8080 inside the container, serve from /var/www/html/public, and run as www-data.

The full tag schema

Every tag is built from three parts, and every part is optional:

serversideup/benchkit-laravel:{php-version}-{variation}-{operating-system}
PartWhen omittedOptions
{php-version}The newest supported PHPA major (8), minor (8.4), or patch (8.4.24) version
{variation}fpm-nginxfpm-nginx, fpm-apache, frankenphp
{operating-system}The current Debian stabletrixie, bookworm, or debian (tracks the current stable)

Leave every part off and you get latest: the newest PHP, on FPM-NGINX, on the current Debian.

Some examples, from loosest to most pinned:

TagWhat you get
latestNewest PHP, FPM-NGINX, current Debian
frankenphpNewest PHP, FrankenPHP
8.4PHP 8.4, FPM-NGINX
8.4-frankenphpPHP 8.4, FrankenPHP
8.5-fpm-apache-bookwormEverything pinned

The live list is on Docker Hub. A PHP version appears there as soon as the application supports it and drops off when it no longer does, so the tag list is the honest answer to "which versions can I compare". There are no Alpine images — Geekbench needs glibc, so the hardware stage would not run there.

Comparing PHP versions

The PHP version is a variable you can move on its own. Hold the variation still, change the version, and run the suite twice on the same machine:

Terminal
docker run -p 80:8080 \
  -v benchkit-runs:/var/www/html/storage/app/runs \
  serversideup/benchkit-laravel:8.4-frankenphp

# then the same thing on the next version up
docker run -p 80:8080 \
  -v benchkit-runs:/var/www/html/storage/app/runs \
  serversideup/benchkit-laravel:8.5-frankenphp

Both containers mount the same runs volume, so the second container still has the first run and the two open side by side in Compare. Each run records the exact PHP version that served it, so they are never mistaken for each other.

Change one thing at a time. 8.4-frankenphp against 8.5-frankenphp measures PHP 8.5. 8.4-fpm-nginx against 8.5-frankenphp measures two things at once, and you will not be able to say which one moved the number.

Comparing variations fairly

Run each variation on the same machine, one after the other, and compare the runs in Compare. Because the hardware and the application are identical, what is left is the serving model.

Two things will spoil that comparison if you let them:

A stock FPM pool is a ceiling, not a measurement. Under PHP-FPM a request occupies a worker for as long as it takes, so the pool size caps concurrency no matter how fast the hardware is. BenchKit flags a run where the pool was the limit.

Neither side is tuned out of the box. A stock pool against a stock FrankenPHP tells you about the defaults rather than about the servers. Compare tuned against tuned, and say which tuning you used.

Tune the pool before you compare. PHP_FPM_PM_MAX_CHILDREN is the one that matters most.

Reading your results covers both in more depth.

FPM-NGINX

The default image and the baseline for every comparison.

FrankenPHP

Runs classic or in Octane worker mode, from the same image.

FPM-Apache

For when Apache is what you run in production.