Tuning/Optimizing Apache on cPanel Servers

source: guiatech.net
source: guiatech.net

cPanel configure Apache to work the most stable way. However, with a few tricks, the default settings can be improved to gain performance and have a better resource usage.

SEPARATE THE SHEEP FROM THE GOATS

Before we start to optimize Apache, you should stop using it to serve static content. Do you know why?
Each Apache process will load PHP and Perl libraries. That’s a waste of resources for serving static content.
If you use NGINX as a reverse proxy for example (I recommend Engintron), you’ll see a considerable decrease on the resources usage.

BEFORE YOU MOVE ON

1. Always keep Apache updated to its latest version;
2. Use MPM Event. If you don’t have it, use EasyApache to recompile Apache;
3. Don’t load useless libraries and extensions;
4. Your kernel is up to date.

TUNING APACHE

WHM » Service Configuration » Apache Configuration » Global Configuration

The only thing you should touch until “Directory /” is the SSL Ciphers.
By default cPanel will accept weak ciphers that won’t help. I’d recommend the follow ciphers:

ALL:!ADH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP

Now we get to the “performance vs resource usage” part:

Start Servers: 5
Minimum Spare Servers: 5
Maximum Spare Servers: 10
Server Limit: 256
Max Request Workers: 150
Max Connections Per Child: 10000
Keep-Alive: On
Keep-Alive Timeout: 5
Max Keep-Alive Requests: 100
Timeout: 300

Let’s translate it to plain English:

Start Servers: 5

Hey Apache, create 5 child process on startup.

Minimum Spare Servers: 5
Maximum Spare Servers: 10

Hey Apache, keep at least 5 child process and no more than 10.

Server Limit (Max: 20.000): 256
Max Request Workers: 150
Max Connections Per Child: 10000

Hey Apache, I want you to handle 150 requests simultaneously. If you reach that, don't go far than ServerLimit. Aaah, don't handle more than 10.000 requests per child (httpd process).

Keep-Alive: On
Keep-Alive Timeout: 5
Max Keep-Alive Requests: 100

Hey Apache, turn Keep-Alive On and allow 100 keep-alive requests, but kill them after 5 seconds.

Timeout: 300

Hey Apache, wait 300 seconds before failing a request.

Ok, so far so good, right? No. No at all. These translations works for MPM Prefork.
Since we are using MPM Event, we have to adapt the right way. According to the Apache documentation:

[..] For threaded and hybrid servers (e.g. event or worker) MaxRequestWorkers restricts the total number of threads that will be available to serve clients. For hybrid MPMs the default value is 16 (ServerLimit) multiplied by the value of 25 (ThreadsPerChild). Therefore, to increase MaxRequestWorkers to a value that requires more than 16 processes, you must also raise ServerLimit.
https://httpd.apache.org/docs/2.4/mod/mpm_common.html#maxrequestworkers

[..] For the worker and event MPMs, this directive in combination with ThreadLimit (https://httpd.apache.org/docs/2.4/mod/mpm_common.html#threadlimit) sets the maximum configured value for MaxRequestWorkers for the lifetime of the Apache httpd process.
https://httpd.apache.org/docs/2.4/mod/mpm_common.html#serverlimit

To make it right, we have to set:

StartServers: 3
Minimum Spare Servers: 3
Maximum Spare Servers: 16
ServerLimit: 16
Max Request Workers: 400 (ServerLimit vs ThreadsPerChild)

The only trick here is, you have to set ServerLimit to 512 and MaxRequestWorkers to 400 and rebuild. Then, you set ServerLimit to 16 and rebuild. cPanel has a “bug” that force MaxRequestWorkes to be smaller or equal to ServerLimit, if both are changed the same time. When you change only ServerLimit in the second time, MaxRequestWorkes won’t be touched.

With a ServerLimit of 16 servers running with 64 threads (ThreadLimit) each, you are able to set Apache to be able to handle 1024 requests (lifetime), which is for most server, more than enough. If you are certain that you need more, use the “Include Editor” to edit ThreadLimit and ThreadsPerChild or raise ServerLimit.

To finish, some people don’t recommend that, but I usually decrease Timeout from 300 to 60. You can see a lower CPU usage when you decrease the Timeout directive, but some scripts may need more than 1 minute to complete.