PHP comparison

nginx + php_fpm vs nginx reverse proxy + apache mod_php vs apache mod_php


Introduction

There are several ways to run PHP on your webserver.

The most popular is to use Apache2 mod_php . It is native way, supported out of the box on most of Linux distributions. If you use hosting with cPanel, this is the most likely way apache is running.

Second popular way is to use nginx + php_fpm (PHP FastCGI Process Manager). It is used on several high performance websites.

From PHP 5.4 or so, php_fpm is part of PHP and is quite stable. Lots of Linux distributions have this as optional PHP package.

It is important to be noted that nginx + php_fpm does not support .htaccess files, so programmers need to make changes to their hosting configurations. With nginx + php_fpm, hosting of legacy applications is almost impossible.

Speaking of high-performance PHP, there is third way that is not widely used. It uses nginx as frontend and Apache2 webserver with mod_php as backend (called nginx + apache mod_php).

With this third way you have the best of both worlds - blazing fast static content and familiar Apache features like .htaccess files in one "package".

Downside of this method is setup complexity.


Test system

All tests were performed on 4 core AMD Opteron 3280 with 16 GB RAM and SATA HDD.

Software versions are as follows:

Apache2 had following configuration

#StartServers 5
MinSpareServers 100
MaxSpareServers 200

This means Apache2 will do almost no forks after initial requests. This is trading speed for system resources.

PHP FPM was set up in similar way:

pm.start_servers        =  100
pm.min_spare_servers    =  100
pm.max_spare_servers    =  200

TCP stack was in "turbo" mode, e.g. tcp_tw_recycle, tcp_tw_reuse.

Test were made with Apache's ab.


Serving Static content

Before making any tests, we need to have some baseline. This is why we decided to check simple HTML file transfer.

Test over localhost:

  requests per second
  no keep alive keep alive
nginx 10,172 not tested
apache2 6,599 not tested

Same test over the internet LAN produced similar even faster result !!!

  requests per second
  no keep alive keep alive
nginx 12,663 34,898
apache2 7,054 28,818

Interestingly both servers worked smoothly without making any spikes in load average.

As expected Apache2 uses more resources.


Serving PHP

For all tests we used very simple PHP file:

<?php
echo "Hello World";

Tests over localhost:

  requests per second
  no keep alive keep alive
nginx + php_fpm 9,681 54,579
nginx + apache2 mod_php 8,571 26,034
apache2 mod_php 6,550 same

It was surprising that apache2 mod_php performed slower that nginx + apache2 mod_php. We believe this is because nginx gets and handle the client request and forwarding it to the Apache2 server with internal keep-alive.

"Real" tests over internet LAN:

  requests per second
  no keep alive keep alive
nginx + php_fpm 11,977 29,053
nginx + apache2 mod_php 11,197 24,134
apache2 mod_php 6,992 22,673

We did perform this test several times.

It is very important that current Apache2 config favours lots of requests.
This means if you perform the test several times, first time you will get lower result and after that you will consistently get higher result.

Another very important consideration is that current Apache2 config had .htaccess files were turned on.
If .htaccess is turned off, results were almost the same.

Conclusion

Apache2 is about 40-50% slower than nginx if you do serve static content, but is still fast enought (~7K requests per second) for most websites.

Apache2 .htaccess is slow. If you can, switch it off.

php_fpm is faster than mod_php, but with just 9 - 10%.
This difference of 10% for sure will go away, if you have real workload with real business logic and database like MySQL, PostgreSQL or even Redis. This is confirmed from a college who did measure nginx vs Apache2.


Raw data for static files

Local nginx static file
=======================

Server Software:        nginx
Server Hostname:        100.100.100.100
Server Port:            80

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      800
Time taken for tests:   9.831 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      25891848 bytes
HTML transferred:       1204272 bytes
Requests per second:    10172.35 [#/sec] (mean)
Time per request:       78.645 [ms] (mean)
Time per request:       0.098 [ms] (mean, across all concurrent requests)
Transfer rate:          2572.08 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       16   35   6.0     34      53
Processing:    18   44   8.2     43      77
Waiting:        2   32   9.6     30      65
Total:         51   78   5.9     78     100

Percentage of the requests served within a certain time (ms)
  50%     78
  66%     81
  75%     82
  80%     83
  90%     86
  95%     87
  98%     90
  99%     92
 100%    100 (longest request)



Local Apache2 static file
=========================

Server Software:        Apache/2.2.32
Server Hostname:        85.25.133.33
Server Port:            8080

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      800
Time taken for tests:   15.154 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      29701782 bytes
HTML transferred:       1200072 bytes
Requests per second:    6599.10 [#/sec] (mean)
Time per request:       121.229 [ms] (mean)
Time per request:       0.152 [ms] (mean, across all concurrent requests)
Transfer rate:          1914.11 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   35 110.6     27    3029
Processing:     1   56 520.6     31   15117
Waiting:        0   49 520.8     24   15117
Total:         14   91 533.0     60   15148

Percentage of the requests served within a certain time (ms)
  50%     60
  66%     66
  75%     70
  80%     73
  90%     79
  95%     83
  98%     95
  99%   1039
 100%  15148 (longest request)



LAN nginx static file
=====================

Server Software:        nginx
Server Hostname:        100.100.100.100
Server Port:            80

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      800
Time taken for tests:   7.896 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      25800000 bytes
HTML transferred:       1200000 bytes
Requests per second:    12663.98 [#/sec] (mean)
Time per request:       63.171 [ms] (mean)
Time per request:       0.079 [ms] (mean, across all concurrent requests)
Transfer rate:          3190.73 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1   40 189.4      5    3014
Processing:     1   19  67.8      5    5046
Waiting:        1   18  67.7      5    5046
Total:          3   59 207.0     10    6053

Percentage of the requests served within a certain time (ms)
  50%     10
  66%     12
  75%     15
  80%     18
  90%     34
  95%    222
  98%   1012
  99%   1017
 100%   6053 (longest request)



LAN Apache2 static file
=======================

Server Software:        Apache/2.2.32
Server Hostname:        100.100.100.100
Server Port:            8080

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      800
Time taken for tests:   14.176 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      29700000 bytes
HTML transferred:       1200000 bytes
Requests per second:    7054.33 [#/sec] (mean)
Time per request:       113.406 [ms] (mean)
Time per request:       0.142 [ms] (mean, across all concurrent requests)
Transfer rate:          2046.03 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   91 348.4      4    7020
Processing:     1   17  88.3      7    2535
Waiting:        1   17  88.3      7    2535
Total:          2  109 359.6     12    7029

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     14
  75%     16
  80%     17
  90%    218
  95%   1013
  98%   1020
  99%   1026
 100%   7029 (longest request)



LAN nginx static file + keep alive
==================================

Server Software:        nginx
Server Hostname:        100.100.100.100
Server Port:            80

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      800
Time taken for tests:   2.865 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    100000
Total transferred:      26300000 bytes
HTML transferred:       1200000 bytes
Requests per second:    34898.06 [#/sec] (mean)
Time per request:       22.924 [ms] (mean)
Time per request:       0.029 [ms] (mean, across all concurrent requests)
Transfer rate:          8963.08 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.9      0      27
Processing:    10   23   2.5     23      58
Waiting:       10   23   2.5     23      58
Total:         10   23   3.0     23      77

Percentage of the requests served within a certain time (ms)
  50%     23
  66%     23
  75%     23
  80%     23
  90%     23
  95%     23
  98%     31
  99%     37
 100%     77 (longest request)



LAN Apache2 static file + keep alive
====================================

Server Software:        Apache/2.2.32
Server Hostname:        100.100.100.100
Server Port:            8080

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      800
Time taken for tests:   3.470 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    99186
Total transferred:      33264349 bytes
HTML transferred:       1200000 bytes
Requests per second:    28818.03 [#/sec] (mean)
Time per request:       27.760 [ms] (mean)
Time per request:       0.035 [ms] (mean, across all concurrent requests)
Transfer rate:          9361.45 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.5      0      25
Processing:     1   13  66.0      7    2907
Waiting:        1   13  66.0      7    2907
Total:          1   13  66.9      7    2931

Percentage of the requests served within a certain time (ms)
  50%      7
  66%      7
  75%      7
  80%      7
  90%      8
  95%      8
  98%     10
  99%     28
 100%   2931 (longest request)

Raw data for PHP files

Local nginx + php_fpm
=====================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            80

Document Path:          /x1.php
Document Length:        162 bytes

Concurrency Level:      800
Time taken for tests:   10.329 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100271
Total transferred:      32888888 bytes
HTML transferred:       16243902 bytes
Requests per second:    9681.94 [#/sec] (mean)
Time per request:       82.628 [ms] (mean)
Time per request:       0.103 [ms] (mean, across all concurrent requests)
Transfer rate:          3109.65 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1   34   5.5     34      53
Processing:     9   48  20.9     46     298
Waiting:        3   37  21.6     36     287
Total:         11   82  19.5     81     325

Percentage of the requests served within a certain time (ms)
  50%     81
  66%     84
  75%     86
  80%     87
  90%     89
  95%     92
  98%     98
  99%    102
 100%    325 (longest request)




Local nginx + php_fpm + keep alive
==================================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            80

Document Path:          /x1.php
Document Length:        162 bytes

Concurrency Level:      800
Time taken for tests:   1.832 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100446
Keep-Alive requests:    100000
Total transferred:      33448518 bytes
HTML transferred:       16272252 bytes
Requests per second:    54579.11 [#/sec] (mean)
Time per request:       14.658 [ms] (mean)
Time per request:       0.018 [ms] (mean, across all concurrent requests)
Transfer rate:          17828.03 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.4      0      40
Processing:     0   14   9.7     10      66
Waiting:        0   14   9.7     10      66
Total:          0   14  10.1     10      80

Percentage of the requests served within a certain time (ms)
  50%     10
  66%     15
  75%     17
  80%     19
  90%     31
  95%     36
  98%     42
  99%     47
 100%     80 (longest request)



Local nginx + apache mod_php
============================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            81

Document Path:          /x1.php
Document Length:        204 bytes

Concurrency Level:      800
Time taken for tests:   11.667 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100224
Total transferred:      41392512 bytes
HTML transferred:       20445696 bytes
Requests per second:    8571.35 [#/sec] (mean)
Time per request:       93.334 [ms] (mean)
Time per request:       0.117 [ms] (mean, across all concurrent requests)
Transfer rate:          3464.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   36   6.4     36      61
Processing:     4   57  14.1     56     305
Waiting:        2   43  13.8     44     289
Total:          9   93  13.8     93     333

Percentage of the requests served within a certain time (ms)
  50%     93
  66%     97
  75%    100
  80%    101
  90%    107
  95%    114
  98%    124
  99%    134
 100%    333 (longest request)




Local nginx + apache mod_php + keep alive
=========================================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            81

Document Path:          /x1.php
Document Length:        204 bytes

Concurrency Level:      800
Time taken for tests:   3.841 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100006
Keep-Alive requests:    100000
Total transferred:      41802508 bytes
HTML transferred:       20401224 bytes
Requests per second:    26034.79 [#/sec] (mean)
Time per request:       30.728 [ms] (mean)
Time per request:       0.038 [ms] (mean, across all concurrent requests)
Transfer rate:          10628.12 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.5      0      44
Processing:     0   24  55.6     13    3037
Waiting:        0   24  55.6     13    3037
Total:          0   24  57.0     13    3056

Percentage of the requests served within a certain time (ms)
  50%     13
  66%     19
  75%     24
  80%     29
  90%     57
  95%     72
  98%     83
  99%     98
 100%   3056 (longest request)



Local apache mod_php
====================

Server Software:        Apache/2.2.32
Server Hostname:        85.25.133.33
Server Port:            8080

Document Path:          /x1.php
Document Length:        204 bytes

Concurrency Level:      800
Time taken for tests:   6.746 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100175
Keep-Alive requests:    99409
Total transferred:      45253740 bytes
HTML transferred:       20435700 bytes
Requests per second:    14823.03 [#/sec] (mean)
Time per request:       53.970 [ms] (mean)
Time per request:       0.067 [ms] (mean, across all concurrent requests)
Transfer rate:          6550.76 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   5.3      0      55
Processing:     2   49 178.9     39    3928
Waiting:        2   49 178.9     39    3928
Total:          2   49 181.5     39    3978

Percentage of the requests served within a certain time (ms)
  50%     39
  66%     41
  75%     43
  80%     45
  90%     47
  95%     49
  98%     52
  99%     83
 100%   3978 (longest request)



LAN nginx + php_fpm
===================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            80

Document Path:          /x1.php
Document Length:        162 bytes

Concurrency Level:      800
Time taken for tests:   8.349 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Total transferred:      32800000 bytes
HTML transferred:       16200000 bytes
Requests per second:    11977.39 [#/sec] (mean)
Time per request:       66.793 [ms] (mean)
Time per request:       0.083 [ms] (mean, across all concurrent requests)
Transfer rate:          3836.51 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   47 231.2      4    3013
Processing:     1   15  48.5      5     893
Waiting:        1   15  48.4      4     893
Total:          2   63 238.1      9    3228

Percentage of the requests served within a certain time (ms)
  50%      9
  66%      9
  75%     10
  80%     11
  90%     25
  95%    216
  98%   1011
  99%   1013
 100%   3228 (longest request)



LAN nginx + php_fpm + keep alive
================================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            80

Document Path:          /x1.php
Document Length:        162 bytes

Concurrency Level:      800
Time taken for tests:   3.442 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Keep-Alive requests:    100000
Total transferred:      33300000 bytes
HTML transferred:       16200000 bytes
Requests per second:    29053.51 [#/sec] (mean)
Time per request:       27.535 [ms] (mean)
Time per request:       0.034 [ms] (mean, across all concurrent requests)
Transfer rate:          9448.07 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.8      0      43
Processing:    10   27   2.8     27      42
Waiting:       10   27   2.8     27      42
Total:         10   27   3.7     27      66

Percentage of the requests served within a certain time (ms)
  50%     27
  66%     27
  75%     28
  80%     28
  90%     31
  95%     32
  98%     36
  99%     40
 100%     66 (longest request)



LAN nginx + apache mod_php
==========================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            81

Document Path:          /x1.php
Document Length:        204 bytes

Concurrency Level:      800
Time taken for tests:   8.930 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Total transferred:      41300000 bytes
HTML transferred:       20400000 bytes
Requests per second:    11197.86 [#/sec] (mean)
Time per request:       71.442 [ms] (mean)
Time per request:       0.089 [ms] (mean, across all concurrent requests)
Transfer rate:          4516.33 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   27 158.2      5    3010
Processing:     1   36 206.8      8    4567
Waiting:        1   36 206.7      8    4564
Total:          1   63 262.5     14    7307

Percentage of the requests served within a certain time (ms)
  50%     14
  66%     18
  75%     21
  80%     24
  90%     37
  95%    219
  98%   1016
  99%   1066
 100%   7307 (longest request)




LAN nginx + apache mod_php + keep alive
=======================================

Server Software:        nginx
Server Hostname:        85.25.133.33
Server Port:            81

Document Path:          /x1.php
Document Length:        204 bytes

Concurrency Level:      800
Time taken for tests:   4.143 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Keep-Alive requests:    100000
Total transferred:      41800000 bytes
HTML transferred:       20400000 bytes
Requests per second:    24134.79 [#/sec] (mean)
Time per request:       33.147 [ms] (mean)
Time per request:       0.041 [ms] (mean, across all concurrent requests)
Transfer rate:          9851.90 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.4      0      40
Processing:     1   24 114.0     13    3819
Waiting:        1   24 114.0     13    3819
Total:          1   24 115.1     13    3819

Percentage of the requests served within a certain time (ms)
  50%     13
  66%     15
  75%     16
  80%     18
  90%     22
  95%     27
  98%     32
  99%     73
 100%   3819 (longest request)



LAN apache mod_php
==================

Server Software:        Apache/2.2.32
Server Hostname:        85.25.133.33
Server Port:            8080

Document Path:          /x1.php
Document Length:        204 bytes

Concurrency Level:      800
Time taken for tests:   14.302 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Total transferred:      41600000 bytes
HTML transferred:       20400000 bytes
Requests per second:    6992.27 [#/sec] (mean)
Time per request:       114.412 [ms] (mean)
Time per request:       0.143 [ms] (mean, across all concurrent requests)
Transfer rate:          2840.61 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   95 342.1      4    7018
Processing:     1   14  39.6      6     831
Waiting:        1   14  39.6      6     831
Total:          2  109 344.9     11    7030

Percentage of the requests served within a certain time (ms)
  50%     11
  66%     13
  75%     14
  80%     16
  90%    218
  95%   1013
  98%   1018
  99%   1022
 100%   7030 (longest request)



LAN apache mod_php + keep alive
===============================

Server Software:        Apache/2.2.32
Server Hostname:        85.25.133.33
Server Port:            8080

Document Path:          /x1.php
Document Length:        204 bytes

Concurrency Level:      800
Time taken for tests:   4.410 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Keep-Alive requests:    99309
Total transferred:      45170301 bytes
HTML transferred:       20400000 bytes
Requests per second:    22673.76 [#/sec] (mean)
Time per request:       35.283 [ms] (mean)
Time per request:       0.044 [ms] (mean, across all concurrent requests)
Transfer rate:          10001.76 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2  35.7      0    1032
Processing:     3   33  54.8     30    1425
Waiting:        3   33  54.8     30    1425
Total:          3   34  86.2     30    2457

Percentage of the requests served within a certain time (ms)
  50%     30
  66%     30
  75%     30
  80%     31
  90%     31
  95%     32
  98%     34
  99%    128
 100%   2457 (longest request)

© 2017-04-26, Nikolay Mihaylov