Modern Apache installations typically come with three Multi-Processing Modules (MPM):
- prefork: Process-based model (non-threaded)
- worker: Hybrid process-thread model
- event: Enhanced version of worker with better keep-alive handling
First, verify which MPM is active in your Apache installation:
httpd -V | grep -i mpm
# Or for newer systems:
apachectl -V | grep -i mpm
To see all loaded modules:
apachectl -M
For a server with 32GB RAM and SSDs, using mpm_event (recommended for Apache 2.4+) or mpm_worker would be optimal. Here's a sample configuration for mpm_event:
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
ServerLimit 16
1. Create or modify the MPM configuration file (typically in /etc/httpd/conf.modules.d/):
# Disable other MPMs
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
LoadModule mpm_event_module modules/mod_mpm_event.so
2. Verify thread safety for your modules:
# Example check for mod_proxy_ajp
apachectl -M | grep proxy_ajp
Use this formula to estimate maximum workers:
MaxRequestWorkers = (Total RAM - (DB + OS + other services)) / Average Apache process size
To measure process size:
ps -ylC httpd --sort:rss | awk '{sum+=$8} END {print sum/NR/1024 "MB"}'
If you encounter "server reached MaxRequestWorkers":
# Temporary solution during traffic spikes
sudo apachectl graceful
For monitoring active connections:
watch -n 1 "echo -n 'Active: '; netstat -an | grep :443 | wc -l"
- Enable keepalive with conservative timeout (KeepAliveTimeout 2-5)
- Set MaxKeepAliveRequests to 100-200
- Configure proper Timeout values (30-60 seconds)
- Enable mod_deflate for compression
- Consider using mod_cache for static content
In CentOS 7 with Apache 2.4.6, you'll typically find three Multi-Processing Modules (MPMs):
# Check installed MPMs
httpd -V | grep -i mpm
# Typical output on CentOS 7:
# Server MPM: prefork
# -D MPMSHARED_ON -D MPM_PREFORK
The evolution from older versions means we now have:
- prefork: Process-based, thread-unsafe modules (PHP 5.x compatibility)
- worker: Hybrid process/thread model (better for static content)
- event: Enhanced version of worker (best for keep-alive connections)
Modern Apache installations separate MPM configurations into dedicated files:
# Location of MPM configs in CentOS 7
/etc/httpd/conf.modules.d/00-mpm.conf
/etc/httpd/conf.d/php.conf
To modify worker settings, create or edit:
/etc/httpd/conf.d/mpm-worker.conf
For Tomcat AJP connectivity with 400 concurrent users, consider:
<IfModule mpm_worker_module>
StartServers 4
ServerLimit 16
ThreadLimit 64
ThreadsPerChild 50
MaxRequestWorkers 800 # (16*50)
MinSpareThreads 100
MaxSpareThreads 400
MaxConnectionsPerChild 10000
</IfModule>
# AJP Connector in Tomcat's server.xml should match:
<Connector port="8009" protocol="AJP/1.3"
maxThreads="500"
minSpareThreads="50"
acceptCount="300"/>
Critical modules for your stack:
# Check thread safety
httpd -M | grep -E 'proxy_ajp|ssl|vhost'
# For PHP (if used):
php -i | grep Thread
Modern versions of these modules are generally thread-safe:
- mod_proxy_ajp (thread-safe since 2.2.x)
- mod_ssl (thread-safe with proper mutexes)
- mod_vhost_alias (thread-safe)
For 32GB RAM server:
# Estimate with:
(Total RAM - (DB + OS + Tomcat)) / Apache_process_size
# Example calculation:
32GB - (12GB MariaDB + 2GB OS + 4GB Tomcat) = 14GB available
14GB / (50MB avg process) ≈ 280 processes
Suggested MaxRequestWorkers: 800 (using threads)
Final optimized configuration:
<IfModule mpm_worker_module>
StartServers 4
ServerLimit 20
ThreadLimit 64
ThreadsPerChild 40
MaxRequestWorkers 800
MinSpareThreads 200
MaxSpareThreads 400
MaxConnectionsPerChild 5000
ListenBacklog 511
AsyncRequestWorkerFactor 2
</IfModule>
# In /etc/sysconfig/httpd add:
export LANG=C
ulimit -n 65536
Post-deployment checks:
# Real-time monitoring
apachectl fullstatus
watch -n 1 "ps -ylC httpd --sort:rss"
# Log format for concurrency analysis:
LogFormat "%{%s}t|%D|%{X-Forwarded-For}i|%s|%b|%r" concurrency_log
CustomLog logs/concurrency_log concurrency_log