Optimizing Apache Prefork MPM: ServerLimit, MaxClients, and MaxRequestsPerChild for High-Traffic Dynamic Sites


1 views

The current prefork configuration appears problematic for several reasons:


    StartServers     800
    MinSpareServers   20
    MaxSpareServers   60
    ServerLimit      900
    MaxClients       900
    MaxRequestsPerChild  2000

With 4GB RAM and 4 Xeon CPUs, these values are extremely aggressive. Each Apache process typically consumes 20-30MB RAM (PHP applications often more). 900 processes would require 27GB RAM - far beyond your 4GB capacity.

For 4GB RAM server with PHP applications, consider:


    StartServers       10
    MinSpareServers     5
    MaxSpareServers    10
    ServerLimit       150
    MaxClients        150
    MaxRequestsPerChild 4000

Calculate realistic values using this formula:

MaxClients = (Total RAM - (OS + Other Services)) / Average Apache Process Size

Example measurement method:

# ps -ylC httpd --sort:rss | awk '{sum+=$8; ++n} END {print "Tot="sum"("n")","Avg="sum/n/1024"MB"}'

Combine with these network optimizations:

Timeout 30
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 100

Implement real-time monitoring with:

# watch -n 1 "echo -n 'Apache Processes: '; ps -C httpd --no-headers | wc -l"

Adjust based on actual traffic patterns. For 5k concurrent users, consider implementing:

  • Varnish cache for static content
  • PHP OPcache
  • Load balancing across multiple servers

For dynamic content, worker or event MPM may be better:


    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0


Your current Apache prefork configuration appears problematic for several reasons:

<IfModule prefork.c>
    StartServers     800
    MinSpareServers   20
    MaxSpareServers   60
    ServerLimit      900
    MaxClients       900
    MaxRequestsPerChild  2000
</IfModule>

The extremely high StartServers value (800) means Apache will immediately spawn 800 processes at startup, consuming significant memory before any traffic arrives. With 4GB RAM, this leaves little room for other processes.

For your 4-core Xeon server with 4GB RAM running a dynamic content site:

<IfModule prefork.c>
    StartServers        4
    MinSpareServers     4
    MaxSpareServers     16
    ServerLimit        200
    MaxClients         200
    MaxRequestsPerChild 10000
</IfModule>

Memory calculation example for PHP processes:

# Typical PHP process memory usage
avg_memory_per_process = 40MB

# Max memory for Apache
max_apache_memory = (Total RAM * 0.8) - (System processes)
                  ≈ (4096MB * 0.8) - 512MB
                  ≈ 2750MB

# Max recommended processes
max_processes = max_apache_memory / avg_memory_per_process
              ≈ 2750 / 40
              ≈ 68

Combine with these KeepAlive settings:

KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 100

Use these commands to monitor effectiveness:

# Check Apache memory usage
ps -ylC httpd --sort:rss

# Real-time server monitoring
watch -n 1 "echo -n 'Processes: '; ps -C httpd --no-headers | wc -l; free -m"

Implementation strategy:

  1. Start with conservative values
  2. Monitor for 24-48 hours
  3. Gradually increase MaxClients in 10% increments
  4. Watch for memory pressure (swap usage)