Apache24-worker/PHP72 – mod_php vs. mod_proxy_fcgi-UDS/PHP-FPM

obsigna

Profile disabled
Which Apache24-worker/PHP72 setup is the better performer on FreeBSD? Searching the internet, I see different results. People seem tending to assume that FastCGI is the better performer, perhaps because it got „Fast“ in its name.

However, the benchmarks which I saw were run on Linux more than 2 years ago, and:
  • we know from this Forums thread that the FreeBSD network stack performed differently (at least in 2014),

  • in many cases the exact details of the setup is not clear
    - pre-forked or threaded Apache?
    - mod_proxy_fcgi over TCP or UDS?
    - enablereuse=on or kept off?

  • I saw PHP7 already working much faster than PHP5 (Apache24-worker + mod_php). The benchmarks which I saw are all run with PHP5, and perhaps there wouldn't be a huge difference anymore when comparing mod_php7 against PHP7-FPM?

  • it is well understood why FastCGI performs better than the original CGI, but I cannot see how all this would make it faster than the dynamically linked-in mod_php which keeps everything in the Apache worker. Only think about the protocol overhead imposed by mod_proxy and mod_proxy_fcgi and also given that a significant number of network connections (either of TCP or UDS) need to be established between the FastCGI daemon and the Apache fcgi-proxy_module – is this negligible, really?
Many doubts and believes, but no exact data. Does anybody got hard figures for the following setups Apache24-worker/PHP72 – mod_php72 vs. mod_proxy+mod_proxy_fcgi/UDS/PHP72-FPM on FreeBSD 11?
 
Last edited:
I executed some tests on a test machine:
Code:
FreeBSD 11.2-BETA1 #0 r333474: Fri May 11 05:22:08 UTC 2018
    root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64
FreeBSD clang version 6.0.0 (tags/RELEASE_600/final 326565) (based on LLVM 6.0.0)
VT(efifb): resolution 800x600
CPU: Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz (4200.15-MHz K8-class CPU)
...

I installed Apache24/PHP72/MySQL56 on it, and copied over my WordPress-BLog. Then I used ftp/wget in recursive mode on a client machine connected over 100 MBit/s wired ethernet for transferring all pages, including hundreds of dynamically generated PHP ones.

Apache24 has been set up with the Worker MPM, and PHP has been compiled with the ZTS option.

The results are:

mod_php72:
Code:
Total wall clock time: 51s
Downloaded: 623 files, 56M in 11s (5.23 MB/s)
CPU utilization of one httpd process = 42 s

php72-fpm listening on a UDS (unix domain socket) without enablereuse=on
Code:
Total wall clock time: 45s
Downloaded: 623 files, 56M in 10s (5.52 MB/s)
CPU utilization for 2 php-fpm pools - 18 s each => 36 s

php72-fpm listening on TCP port 9000 on 127.0.0.1 without enablereuse=on
Code:
Total wall clock time: 46s
Downloaded: 623 files, 56M in 10s (5.53 MB/s)
CPU utilization for 2 php-fpm pools - 18.5 + 17.5 s => 36 s

Setting enablereuse=on on the TCP socket did not speed up page generation but added 2 more php-fpm pools.

Conclusion, php72-fpm listening on the UDS is about (51/45 - 1)*100 = 13.3 % faster than mod_php72. Perhaps, the work of mod_php72 is not as well balanced on the 8 HT cores of the given machine when compared to the separate PHP-FPM pools.
 
Last edited:
Why apache and not nginx if benchmarking for speed? I am using nginx, php-fpm and fcgiwrap with Zoneminder along with mysql.
 
Why apache and not nginx if benchmarking for speed? ...
I am using Apache for most of my professional life, and I know enough about it to make it dancing and singing. About nginx, I know nothing, except that it got an ugly name. I try to avoid software having funny names, like Linux, GNUthehell, and just nginx :-D

Seriously, in the FPM runs, the httpd processes where kept at almost zero CPU load, so I would expect not more than a few milliseconds of overall performance improvement by switching to another web server.
 
I executed some tests on a test machine:

[ .. ] Then I used ftp/wget in recursive mode on a client machine connecte over 100 MBit/s wired ethernet for transferring all pages, including hundreds of dynamically generated PHP ones. [ .. ]

Try using the ab (Apache Benchmark) tool here. You can specifiy concurrency, and things will heat up a bit more. If you do it with wget, I'd put a bunch of unique urls in a file, and:

Code:
cat <file> | xargs -n1 -P10 wget -qO /dev/null

.. change the -P parameter to get more or less (than 10 wgets) running at the same time.

It's crude.. but it works.
 
Oh and to answer your question: preferably I'd run FPM/UDM. Only mod_php if very very lazy :). Would rather forget all other forms of (fast)cgi. Also good to explore is Apache/Event with FPM. Alot more towards nginx in terms of performance and memory footprint. But also more difficult to tune. Worker was easy in that regard. That's why I still mostly go with Worker (without mod_php loaded), and FPM for PHP.
 
In the (quite distant) past I had non-realistic results using ab(1), and therefore I disconsidered it for the present tests. Another point is, that it works on one page only, for example the initial WordPress-BLog page. Here it is the compiled digest of the last 25 BLog entries (ca. 128 kB of HTML in total). Anyway, here come the results for ab -c 4 -n 50 http://obsigna.intranet/
mod_php72:
Code:
Server Software:        Apache
Server Hostname:        obsigna.intranet
Server Port:            80

Document Path:          /
Document Length:        129321 bytes

Concurrency Level:      4
Time taken for tests:   2.293 seconds
Complete requests:      50
Failed requests:        0
Total transferred:      6476450 bytes
HTML transferred:       6466050 bytes
Requests per second:    21.81 [#/sec] (mean)
Time per request:       183.426 [ms] (mean)
Time per request:       45.857 [ms] (mean, across all concurrent requests)
Transfer rate:          2758.46 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.9      1       3
Processing:   160  175   8.0    174     206
Waiting:      112  122   7.0    121     155
Total:        162  177   8.0    175     208

Percentage of the requests served within a certain time (ms)
  50%    175
  66%    178
  75%    179
  80%    180
  90%    185
  95%    194
  98%    208
  99%    208
 100%    208 (longest request)
php72-fpm listening on a UDS:
Code:
Server Software:        Apache
Server Hostname:        obsigna.intranet
Server Port:            80

Document Path:          /
Document Length:        129321 bytes

Concurrency Level:      4
Time taken for tests:   2.320 seconds
Complete requests:      50
Failed requests:        0
Total transferred:      6476450 bytes
HTML transferred:       6466050 bytes
Requests per second:    21.55 [#/sec] (mean)
Time per request:       185.622 [ms] (mean)
Time per request:       46.406 [ms] (mean, across all concurrent requests)
Transfer rate:          2725.82 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       1
Processing:   139  181  42.5    160     287
Waiting:       97  134  43.9    108     244
Total:        140  181  42.4    161     288

Percentage of the requests served within a certain time (ms)
  50%    161
  66%    203
  75%    207
  80%    211
  90%    273
  95%    279
  98%    288
  99%    288
 100%    288 (longest request)

ab tells us, that mod_php72 performs a little bit better than php72-fpm/UDS - let's say it is the same performance, but in addition, the distribution of the response times of mod_php72 is more uniform.
 
... Also good to explore is Apache/Event with FPM. Alot more towards nginx in terms of performance and memory footprint. But also more difficult to tune. Worker was easy in that regard. That's why I still mostly go with Worker (without mod_php loaded), and FPM for PHP.

I explored Apache with the Event-MPM, and it performed worse in the wget test runs compared to the Worker-MPM, while at the same time it launched more httpd processes. AFAIK, the Event-MPM is a mixture of the threaded with the forking concurrency model, and IMHO, this concept doesn't even look good on the paper. I like the Worker-MPM for its behaviour being clean and well understood (by me).
 
Which Apache24-worker/PHP72 setup is the better performer on FreeBSD? Searching the internet, I see different results. People seem tending to assume that FastCGI is the better performer, perhaps because it got „Fast“ in its name.
Could you post here examples of your config files for Apache 2.4 to enable MPM please.
I tried Apache 2.4 (mpm_event+mod_proxy_fcgi) what other alternatives exist for Apache 2.4.
 
You won’t enable MPM. You would choose among the MPM models prefork, worker and event the one which best fits your workload. Edit the Apache’s main configuration file /usr/local/etc/apche24/httpd.conf and remove the hash sign in front of the MPM which you want to use and put a hash sign in front of the other two. My config is:
Code:
...
#LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so
#LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so
LoadModule mpm_worker_module libexec/apache24/mod_mpm_worker.so
...

My above mentioned benchmarks revealed no significant performance difference between mod_php and mod_proxy_fcgi-UDS, and for this reason, I stay with mod_php because IMHO it is more easy to setup.

Provided you got Apache24 already installed, then usually your’e done with:
pkg install mod_php73
 
You won’t enable MPM. You would choose among the MPM models prefork, worker and event the one which best fits your workload. Edit the Apache’s main configuration file /usr/local/etc/apche24/httpd.conf and remove the hash sign in front of the MPM which you want to use and put a hash sign in front of the other two. My config is:
Yes you are right and you are using MPM_worker instead of MPM_event but what about the other part which is below in your httpd.conf? Could you post the whole httpd.conf and other included files (if you change something in them) from apache24/Includes/*.conf ?

Sometimes it's the only working configuration. Also it's very easy to setup.
 
Sometimes, when in a hurry, people forget the magic word when asking for help. Anyway, you’re welcome :-D. Look here:
Sorry about the magic word and big thanks to you for provided config. With it I have even more questions than answers haha. But some parts of it are clearly understandable. Maybe you can advise me in my case please. My config is much simplier (below are most important parts) maybe I forgot something and that is why I having some glitches while mod_proxy_fcgi activated.


Code:
LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so
LoadModule authn_file_module libexec/apache24/mod_authn_file.so
LoadModule authn_core_module libexec/apache24/mod_authn_core.so
LoadModule authz_host_module libexec/apache24/mod_authz_host.so
LoadModule authz_groupfile_module libexec/apache24/mod_authz_groupfile.so
LoadModule authz_user_module libexec/apache24/mod_authz_user.so
LoadModule authz_core_module libexec/apache24/mod_authz_core.so
LoadModule authnz_fcgi_module libexec/apache24/mod_authnz_fcgi.so
LoadModule access_compat_module libexec/apache24/mod_access_compat.so
LoadModule auth_basic_module libexec/apache24/mod_auth_basic.so
LoadModule reqtimeout_module libexec/apache24/mod_reqtimeout.so
LoadModule filter_module libexec/apache24/mod_filter.so
LoadModule deflate_module libexec/apache24/mod_deflate.so
LoadModule xml2enc_module libexec/apache24/mod_xml2enc.so
LoadModule mime_module libexec/apache24/mod_mime.so
LoadModule log_config_module libexec/apache24/mod_log_config.so
LoadModule env_module libexec/apache24/mod_env.so
LoadModule headers_module libexec/apache24/mod_headers.so
LoadModule setenvif_module libexec/apache24/mod_setenvif.so
LoadModule version_module libexec/apache24/mod_version.so
LoadModule unixd_module libexec/apache24/mod_unixd.so
LoadModule status_module libexec/apache24/mod_status.so
LoadModule autoindex_module libexec/apache24/mod_autoindex.so
LoadModule dir_module libexec/apache24/mod_dir.so
LoadModule alias_module libexec/apache24/mod_alias.so
LoadModule rewrite_module libexec/apache24/mod_rewrite.so

SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1

<Directory />
    AllowOverride none
    Require all denied
</Directory>

<IfModule dir_module>
    DirectoryIndex index.php
</IfModule>

<Files ".ht*">
    Require all denied
</Files>

<Directory "/usr/local/www/apache24/data">
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

<Proxy "*">
    Require ip 127.0.0.1
</Proxy>

<FilesMatch \.php$>
        SetHandler proxy:fcgi://127.0.0.1:9000
</FilesMatch>

Currently if mpm_prefork + mod_php activated - php webapplication is stable, but if mpm_event or mpm_worker + mod_proxy_fgi activated - php webapllication is unstable. What other threaded config can be? I thought about something like mpm_event or mpm_worker + ap24-mod_fcgid or mpm_event or mpm_worker + mod_cgid? Correct me if I'm wrong please.
 
To begin with, I do not use FCGI for PHP, instead, as I said earlier, PHP is served via mod_php see in my httpd.conf:
LoadModule php7_module libexec/apache24/libphp7.so

I use FCGI for my ContentCGI daemon which let me edit my BLog in a WYSIWYG manner. I don't have running PHP-FPM on my sites, and therefore here come only 2 observations:
  1. If you want to use Apache’s FCGI-Proxy, then you need to load the following modules:
    LoadModule proxy_module libexec/apache24/mod_proxy.so
    LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so

  2. Of course the PHP-FCGI daemon must be running, so check whether you have in your /etc/rc.conf the following entry: php_fpm_enable="YES"
Good luck.
 
To begin with, I do not use FCGI for PHP, instead, as I said earlier, PHP is served via mod_php see in my httpd.conf:
LoadModule php7_module libexec/apache24/libphp7.so
Sorry I noticed that module but didn't know that pkg install mod_php71 add this line to the httpd.conf. So you compiled its threaded version? Because if I switch from mpm_prefork to mpm_event or mpm_worker I have a message that "your PHP Module not threadsafe. You need to recompile PHP.".
I don't have running PHP-FPM on my sites
But why? Usually I use mpm_event + php-fpm + mod_proxy_fcgi for php and this config faster than mod_php (non-threadsafe).
If you want to use Apache’s FCGI-Proxy
Actually I want to get my php website working faster and trying to reproduce setups from here https://cwiki.apache.org/confluence/display/HTTPD/PHP but no luck yet. So maybe if you know about Apache so much to able to make it "dancing and singing" you would be so kind to help me to find my config mistakes please.
 
...
But why? Usually I use mpm_event + php-fpm + mod_proxy_fcgi for php and this config faster than mod_php (non-threadsafe). ...

Faster? These are fake news, or alternative facts, how ewer you want to call it. I did the benchmarks, and neither the event MPM was superior over the worker MPM, nor FCGI was superior over mod_php. But both added another layer of complication, see this #8 and this #7.

...
Actually I want to get my php website working faster and trying to reproduce setups from here https://cwiki.apache.org/confluence/display/HTTPD/PHP but no luck yet. So maybe if you know about Apache so much to able to make it "dancing and singing" you would be so kind to help me to find my config mistakes please.

I did my tests in May 2018 and the test machine does other things now and all the PHP-FCGI installation has gone. I don't have time to install everything again. I stay with my results, because the tests were carried out carefully (s. above). If you want to force other results, I cannot be of any help with it.
 
Last edited:
obsigna
Seems like you haven't noticed some of my questions. Your mod_php work with mod_mpm_worker but mine not (because of not threadsafe). How to config webserver to be threaded with mod_php?
Faster? These are fake news, or alternative facts, howewer you want to call it. I did the benchmarks, and neither the event MPM was superior over the worker MPM, nor FCGI was superior over mod_php. But both added another layer of complication, see this #8 and this #7.
As faster as I can see with my unaided eye. You can try it by yourself by installing as an example default Prestashop CMS to a fresh VPS and perform some clicking on a frontend and on a backend. Also to my subjective view I would say that mod_cgid is similar to mod_php in the sense of speed on low loaded webserver.
 
Faster? These are fake news, or alternative facts, howewer you want to call it. I did the benchmarks, and neither the event MPM was superior over the worker MPM, nor FCGI was superior over mod_php. But both added another layer of complication, see this #8 and this #7.

Please dont use your personal experience as gernal assumption. Its fine if it works for you, but there are plenty of benchmarks (just google) say the other. I would say, the bigger the installation the better is the performance gain of fcgi/fpm. Ofc, you have to configure the fpm daemons right.
 
Faster? These are fake news, or alternative facts, howewer you want to call it. I did the benchmarks, and neither the event MPM was superior over the worker MPM, nor FCGI was superior over mod_php. But both added another layer of complication, see this #8 and this #7.
As faster as I can see with my unaided eye. You can try it by yourself by installing as an example default Prestashop CMS to a fresh VPS.
 
How to config webserver to be threaded with mod_php?
If you have choose mpm_worker or mpm_event, then you must do the followings:

Type "cd /usr/ports/www/mod_php7x", where x is a number between (1 and 3) depending on what version of PHP you have, AND press the ENTER button.
Type "make config" and choose the option "Force ZEND Thread Safety (ZTS) Build" , AND press the ENTER button.
Type "make build install" , AND press the ENTER button.

Note: You must have enabled thread safety option in your PHP7x before now and successfully built it. If you have not, go to "/usr/ports/lang/php7x", select "Force ZEND Thread Safety (ZTS) Build" and run the make commands too.
 
Please dont use your personal experience as gernal assumption. Its fine if it works for you, but there are plenty of benchmarks (just google) say the other. I would say, the bigger the installation the better is the performance gain of fcgi/fpm. Ofc, you have to configure the fpm daemons right.

Througout the whole present thread I made very clear the measurement methods and how I came to the results. Now proton1234 is challenging me, why I am using mod_php instead of PHP-FPM. And my answer is, because I didn't see a significant difference in my setup which justifies the extra hassle. Now he is insisting that my results are wrong and his results with his non-working Prestashop CMS installed on the base of his non-working Proxy-FCGI + PHP-FPM show a better performance which is perceptible with the bare eyes. Please give me a break. Everybody may install anything to their liking, but I won't waste my time with this any furter. Good Luck.
 
Througout the whole present thread I made very clear the measurement methods and how I came to the results. Now proton1234 is challenging me, why I am using mod_php instead of PHP-FPM. And my answer is, because I didn't see a significant difference in my setup which justifies the extra hassle. Now he is insisting that my results are wrong and his results with his non-working Prestashop CMS installed on the base of his non-working Proxy-FCGI + PHP-FPM show a better performance which is perceptible with the bare eyes. Please give me a break. Everybody may install anything to their liking, but I won't waste my time with this any furter. Good Luck.

That may be true for you, but that was not my point. You called the whole statement that fcgi/fpm in general gives better performance wrong. Thats just not the case and if u call such things u should have better proof than your experience. Ofc it may be also true that for your specific case it doenst matter what you are using.
 
Back
Top