Benchmarking Laravel, Symfony, & Zend

A variety of benchmarks comparing PHP frameworks float around the web. However, they are often comparing “apples” to “oranges”. In particular, I want to focus on Laravel, Symfony, and Zend and why these three frameworks are often benchmarked incorrectly against each other.

You don’t have to take my word for it. After reading this post you can spin up your own 2GB DigitalOcean server and test these results for yourself in about 5 minutes.

Before beginning, know that all of these frameworks are fast enough to handle any application you are ever likely to build. I hesitated to even write this post because I think PHP’s unique obsession with benchmarking on this level is really, really silly. My only goal is to show how to perform a fair comparison between the three.

The Problem

When you first configure a Symfony or Zend project on a fresh DigitalOcean server, you will see that there is no session information being returned. Note how no cookies are present on the site:

However, Laravel ships with sessions (and other middleware) enabled out of the box on the default landing page. This is convenient because most web applications built using these frameworks use sessions to persist user state. I leave this as the default for user convenience even though it hurts the framework in naive benchmark comparisons.

Another common mistake is either not dumping an optimized Composer autoloader or not caching the Laravel configuration using the php artisan config:cache command, which saves a significant amount of bootstrap time.

The Setup

I created a 2GB DigitalOcean PHP 7.1 server using Laravel Forge. I installed Symfony, optimized the Composer autoloader, and configured Nginx to serve Symfony through the production (app.php) front-controller. I also followed the steps in the Symfony production tuning guide. I followed the same basic procedure for Zend.

Next, I configured PHP 7.1’s opcache for production with the following settings:

opcache.enable=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=1

When installing Laravel, I ran the config:cache Artisan command and commented out the middleware in the web middleware group of the app/Http/Kernel.php file. These are the middleware responsible for enabling sessions. This change allows me to test all three frameworks without session handling.

The Results

After configuring the projects, I ran a simple test using Apache benchmark, which anyone can recreate:

ab -t 10 -c 10 http://server.address/

Here are the results:

Without Sessions:

  • Laravel: 609.03 requests per second (mean)
  • Zend: 559.91 requests per second (mean)
  • Symfony: 532.97 requests per second (mean)

With Sessions:

  • Laravel: 521.64 requests per second (mean)
  • Zend: 484.94 requests per second (mean)
  • Symfony: 439.37 requests per second (mean)