When Apache's worker threads max out at 256 concurrent connections (the default compiled limit), you'll see exactly what you described:
256 requests currently being processed, 0 idle workers
This creates a queuing effect where new connections must wait for available workers, resulting in increased latency or connection timeouts.
Before modifying Apache's configuration, verify your server can handle increased connections:
# Calculate maximum potential memory usage
grep 'MaxClients' /etc/httpd/conf/httpd.conf
ps aux | grep 'httpd' | awk '{print $6/1024 " MB"}' | sort -n
Example output showing memory usage per Apache process:
25.32 MB
26.45 MB
27.11 MB
(...)
Multiply the largest process size by your desired MaxClients value to ensure sufficient RAM.
For modern servers with adequate resources, edit httpd.conf:
# For prefork MPM
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 400
MaxRequestsPerChild 4000
</IfModule>
# For worker MPM
<IfModule mpm_worker_module>
ServerLimit 100
ThreadLimit 64
StartServers 2
MaxClients 3200
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
</IfModule>
After modifying, gracefully restart Apache:
apachectl -k graceful
Identify slow requests with mod_status enabled:
ExtendedStatus On
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
Then analyze with:
watch -n 1 "curl -s http://localhost/server-status | grep -E 'W|R|K' | wc -l"
For modern Apache 2.4+ installations, switch to event MPM:
# Stop Apache
service httpd stop
# Switch MPM
yum remove httpd
yum install httpd24u-event
# Configure event MPM
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 800
MaxConnectionsPerChild 0
</IfModule>
Validate configuration with ab (Apache Benchmark):
ab -n 1000 -c 100 http://yoursite.com/testpage.html
# Monitor during test
watch -n 1 "netstat -ant | awk '\$6 == \"ESTABLISHED\" {print \$5}' | cut -d: -f1 | sort | uniq -c | sort -n"
Remember to monitor memory usage during peak loads and adjust accordingly.
When your Apache server reaches its default connection limit, you'll see symptoms like:
server-status output:
256 requests currently being processed, 0 idle workers
Load average remains low (e.g., 2.69 on 8 CPUs)
Memory usage under 30%
Option 1: Temporary Connection Increase
Edit your httpd.conf:
# For non-threaded MPM (prefork)
<IfModule mpm_prefork_module>
ServerLimit 400
MaxClients 400
StartServers 10
MinSpareServers 5
MaxSpareServers 20
</IfModule>
# For threaded MPM (worker)
<IfModule mpm_worker_module>
ServerLimit 100
ThreadLimit 64
StartServers 4
MaxClients 4000
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
Remember to restart Apache after changes:
sudo service httpd graceful # RHEL/CentOS
sudo systemctl reload apache2 # Debian/Ubuntu
PHP Process Management
Optimize your PHP-FPM pool settings:
[www]
pm = dynamic
pm.max_children = 100
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 500
Reverse Proxy Setup
Implement Nginx as reverse proxy to handle static content:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
root /var/www/html;
expires 30d;
}
}
KeepAlive Optimization
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 100
Module Management
Disable unused modules in httpd.conf:
# Example of modules to potentially disable
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authn_file_module modules/mod_authn_file.so
# Keep enabled:
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
Create a real-time monitoring script:
#!/bin/bash
while true; do
echo -n "Connections: "
netstat -an | grep :80 | wc -l
echo -n "Apache workers: "
apachectl fullstatus | grep "requests currently being processed"
echo "---"
sleep 5
done
Use mod_status for detailed analysis:
<Location /server-status>
SetHandler server-status
Require host localhost
</Location>
Consider these scalable setups:
1. Nginx (frontend) -> Apache (backend)
2. Varnish Cache -> Apache
3. Cloudflare/Load Balancer -> Multiple Apache instances
For source installations:
# Edit include/ap_mmn.h before compiling
#define HARD_SERVER_LIMIT 256 # Change to 1024 or higher
./configure --prefix=/usr/local/apache2 \
--enable-mods-shared=most \
--with-mpm=prefork
make && make install