nginx + php_fpm vs nginx reverse proxy + apache mod_php vs apache mod_php
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.
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.
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.
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.
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.
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)
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)