I was going to dump this in the ModSecurity thread, but I think it's gonna blow up with a ton of config dumps so I guess a new thread will work better for organizing things. I spent some time optimizing Apache and PHP today and got some good results = everything in the backend of sites is much snappier, initial connections to sites is much faster, TTFB dropped to 30ms to 50ms (previously 200ms avg, and was 150ms on OLS tests).
I did find one kind of critical flaw in Enhance though = we need a way to set php-fpm config on a per-website (account) basis, OR even better would be a php-fpm config on a per-package basis... There's just no way to have a one-size-fits-all config that runs on a per-website (account) basis when we can have websites (accounts) with 2GB ram allocation and 10gb ram allocation on the same server.
Important locations of files for reference:
Apache default config: /var/local/enhance/apache
php-fpm default config: I just su into a user and run php-fpm -tt
ModSecurity config file (this is the same file that gets updated from the ModSec config in Enhance UI): /etc/modsecurity.d/modsecurity.customisations.conf
Where I'm adding customizations:
For the most part in the network wide areas in Enhance UI in "Settings>Service" for php-fpm directives. Then for Apache/MPM configs I'm adding them in the ModSecurity config for each server as it's an easy way to alter Apache config through the UI. I do keep FTP connected and viewing the modsec folder any time I'm editing that file in Enhance, because if it gets a bad config it will crash and need to fix the file directly via FTP, so best just have the window ready to go.
Some rambling about rationale for config changes
I would say many of the default configs are probably okay for small/medium sized servers. For example the ServerLimit is default 256, which would likely only be suitable for a server up-to 8cpu/32gb ram. For a larger server, it will need to be opened way up. More limiting factors for php-fpm = defaults aren't optimized for best performance as you can see in the default config I will paste below. It's set to 25 max children which could handle a pretty good amount of traffic for a small site - if we figured 50mb per process it would consume a bit over 1gb ram, it may be a safe setting for small hosting accounts - but what if you have a large Package with 10gb ram? Well now that package is going to perform very poorly and have a whole lot of unused ram, if it's a busy site then the traffic will be slow... This is why I mentioned that per-website php-fpm config is necessary, you can't have a very large mix of Packages on the same server since they currently all have to use the same php-fpm config.
More impact on pagespeed/TTFB = pm is set to ondemand and start_servers and min/max_spare_servers are set to 0. That's probably Enhance trying to make slow/dormant hosting accounts not consume very much resources due to people complaining about that so much (derp). For me, I want my accounts to be tuned for PERFORMANCE, so I switched the pm to dynamic so that I can have processes warmed up and ready to go as soon as a request comes in. I also set a start servers and min/max spare servers.
Apache/mpm_event optimizations:
HostnameLookups Off
LimitRequestFieldSize 16380
MaxConnectionsPerChild 5000
ServerLimit 2000
StartServers 10
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestWorkers 2000
MaxKeepAliveRequests 500
KeepAlive On
KeepAliveTimeout 5
That's my config for a 50cpu/250gb ram server, that config is going to probably use about up-to 100GB ram if needed. Note I still need to optimize SSL/TLS, which I'll get back to later. LimitRequestFieldSize was increased because on Apache it's default is I think 4kb, while on other systems like nginx it's 16kb, and I've found a lot of clients with ads on their sites will get errors if the http headers are too limited as the ads can sometimes have too large of cookies. And of course hostnamelookup + keepalive are just more speed things.
Next on to php-fpm, this one is a bit more simple as these configs are mostly just affecting things on a smaller level (per-"website"). As I said before I set to dynamic because I want my workers warmed up and ready to go - they'll consume more ram while idle, but that's fine, my clientele want the best and fastest, and I have 250gb of ram that I want to be USED not just sitting unused all the time. Maybe for someone selling low-end hosting packages they would want the config to stay on ondemand to keep resource usage lower so they can cram a few hundred more customers on their server.
pm = dynamic
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 1000
pm.max_children = 100
Now this config is more suitable for a Package that has around 10GB ram allocation. Unfortunately, as noted earlier we can't set php-fpm config on per-website (account) basis, so I'm just dumping the config that works for my largest Package and calling it good (smaller sites might run into OOM scenarios if they get a burst of traffic that consumes all memory on their account, at which point it will need to be a conversation about upgrading their package or something I guess). It's a sucky tradeoff having to make one php-fpm config for all sites on a server, but if you have to choose I'd go with optimizing for the biggest package, and the smaller ones will hopefully just upgrade if running into OOM situations.
It will be nice if Enhance will give a per-website (account) php-fpm config. I'd guess it's something that will happen eventually, it kind of has-to.
Final thoughts:
I'd encourage everyone wanting to optimize their config to read about all the settings I've listed above, find out what they all mean and how they work/affect each other. My next step is to optimize SSL/TLS, after that it's going to be testing my config at high load.
For reference, here's the default php-fpm config:
[global]
pid = undefined
error_log = /dev/null
syslog.ident = php-fpm
syslog.facility = 24
log_buffering = yes
log_level = unknown value
log_limit = 1024
emergency_restart_interval = 0s
emergency_restart_threshold = 0
process_control_timeout = 0s
process.max = 0
process.priority = undefined
daemonize = yes
rlimit_files = 0
rlimit_core = 0
events.mechanism = epoll
[www]
prefix = undefined
user = undefined
group = undefined
listen = 0.0.0.0:9000
listen.backlog = -1
listen.owner = undefined
listen.group = undefined
listen.mode = undefined
listen.allowed_clients = undefined
process.priority = undefined
process.dumpable = no
pm = ondemand
pm.max_children = 25
pm.start_servers = 0
pm.min_spare_servers = 0
pm.max_spare_servers = 0
pm.max_spawn_rate = 32
pm.process_idle_timeout = 10
pm.max_requests = 0
pm.status_path = undefined
pm.status_listen = undefined
ping.path = undefined
ping.response = undefined
access.log = undefined
access.format = undefined
slowlog = undefined
request_slowlog_timeout = 0s
request_slowlog_trace_depth = 20
request_terminate_timeout = 0s
request_terminate_timeout_track_finished = no
rlimit_files = 0
rlimit_core = 0
chroot = undefined
chdir = undefined
catch_workers_output = no
decorate_workers_output = yes
clear_env = yes
security.limit_extensions = .php .phar