Perfect! I ran some tests today with tweaking various numbers and looked at recommendations online too. It's mostly a copy of yours @imc67 in the end but with a lower MaxConnectionsPerChild. Ran a bunch of different tests with different numbers but concluded that was the best bang for the buck so-to-speak given the 4 GB memory max set on each WP app.
It's a mix of default values from the Ubuntu install and the default Apache values in the original package too (for the 256 MaxRequestWorkers for example). I'm pleased with the results. ๐
Here's what I have for reference now, and I used ab (Apache Benchmark) to run some performance tests and had significant improvements over the defaults. Thought I'd share the testing results in case anyone was interested.
New mpm_prefork.conf I'm using:
# Restart the app if you make changes to this file
<IfModule mpm_prefork_module>
# On startup, start these many servers
StartServers 5
# At any given time, keep atleast these many servers
MinSpareServers 5
# At any given time, keep atmost these many idle servers (this is always >= MinSpareServers+1)
MaxSpareServers 10
# Maximum number of servers at any given instant. Requests will be queued after this
MaxRequestWorkers 256
# Recycle process after handling these many requests. This protected against accidental memory leaks
MaxConnectionsPerChild 500
</IfModule>
Resources:
https://httpd.apache.org/docs/2.4/mod/prefork.html
https://exampleconfig.com/view/apache-ubuntu20-04-etc-apache2-mods-available-mpm_prefork-conf
https://www.woktron.com/secure/knowledgebase/133/How-to-optimize-Apache-performance.html
https://www.maketecheasier.com/optimizing-apache-part-1/
Results from ab with default settings that come with Cloudron's WP package: (note the rather large spread between min and max request times)
Concurrency Level: 50
Time taken for tests: 12.391 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 84813000 bytes
HTML transferred: 84205000 bytes
Requests per second: 80.70 [#/sec] (mean)
Time per request: 619.574 [ms] (mean)
Time per request: 12.391 [ms] (mean, across all concurrent requests)
Transfer rate: 6684.04 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 227 291 36.4 287 401
Processing: 220 281 122.2 252 1039
Waiting: 144 190 120.0 161 954
Total: 451 572 127.3 546 1285
Percentage of the requests served within a certain time (ms)
50% 546
66% 570
75% 584
80% 594
90% 624
95% 818
98% 1091
99% 1261
100% 1285 (longest request)
Results after tweaking to the above new configuration: (note that the max request time here is about 60% faster still than original config results and overall a much more consistent behaviour too!)
Concurrency Level: 50
Time taken for tests: 11.358 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 84813000 bytes
HTML transferred: 84205000 bytes
Requests per second: 88.04 [#/sec] (mean)
Time per request: 567.899 [ms] (mean)
Time per request: 11.358 [ms] (mean, across all concurrent requests)
Transfer rate: 7292.24 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 230 287 26.9 283 389
Processing: 220 252 17.3 249 329
Waiting: 144 160 10.0 157 217
Total: 467 539 33.0 538 649
Percentage of the requests served within a certain time (ms)
50% 538
66% 550
75% 559
80% 567
90% 584
95% 599
98% 618
99% 622
100% 649 (longest request)