Introduction
When Apache's MaxRequestWorkers limit is reached, the server stops accepting new connections and returns 503 Service Unavailable to clients. The error log records:
[Mon Apr 08 20:30:15.123456 2026] [mpm_prefork:error] [pid 1234] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers settingThis occurs when concurrent requests exceed the configured worker capacity, often during traffic spikes or when requests are held open by slow backend processing.
Symptoms
- Clients receive 503 Service Unavailable responses
- Apache error log shows "server reached MaxRequestWorkers setting"
apachectl statusshows all worker slots as "W" (writing response) or "K" (keepalive)- New connections queue and eventually time out
- Server appears to stop responding while existing requests are still processing
Common Causes
MaxRequestWorkersset too low for actual traffic volume- Slow PHP or application responses holding worker slots open for extended periods
- KeepAlive connections occupying worker slots while idle
- Memory limit per Apache process restricting how high MaxRequestWorkers can be set
- No connection queuing mechanism, requests are dropped immediately when limit is reached
Step-by-Step Fix
- 1.Check current Apache MPM configuration:
- 2.```bash
- 3.apachectl -V | grep -i mpm
- 4.sudo apachectl status --no-pager | head -40
- 5.
` - 6.Identify whether you are using
mpm_prefork,mpm_worker, ormpm_event. - 7.Increase MaxRequestWorkers in the appropriate MPM configuration. For event MPM at
/etc/apache2/mods-available/mpm_event.conf: - 8.```apache
- 9.<IfModule mpm_event_module>
- 10.StartServers 4
- 11.MinSpareThreads 25
- 12.MaxSpareThreads 75
- 13.ThreadLimit 64
- 14.ThreadsPerChild 25
- 15.MaxRequestWorkers 400
- 16.MaxConnectionsPerChild 10000
- 17.ServerLimit 16
- 18.</IfModule>
- 19.
` - 20.
MaxRequestWorkers = ServerLimit x ThreadsPerChild. With the values above: 16 x 25 = 400. - 21.Calculate the safe maximum based on available memory:
- 22.```bash
- 23.ps -eo pid,rss,comm | grep apache2 | awk '{sum+=$2} END {print "Avg RSS:", sum/NR/1024, "MB"}'
- 24.
` - 25.If each Apache process uses 60MB and you have 8GB RAM reserved for Apache:
8192 / 60 = ~136maximum workers. - 26.Reduce KeepAlive timeout to free worker slots faster:
- 27.```apache
- 28.KeepAlive On
- 29.KeepAliveTimeout 5
- 30.MaxKeepAliveRequests 100
- 31.
` - 32.Lower
KeepAliveTimeoutfrom the default 15s to 5s so idle connections release worker slots sooner. - 33.Enable mod_status monitoring to track worker usage in real time:
- 34.```apache
- 35.<Location "/server-status">
- 36.SetHandler server-status
- 37.Require ip 127.0.0.1 ::1 10.0.0.0/8
- 38.</Location>
- 39.ExtendedStatus On
- 40.
` - 41.Access at
http://localhost/server-statusto see real-time worker allocation. - 42.Test and restart:
- 43.```bash
- 44.sudo apachectl configtest
- 45.sudo systemctl restart apache2
- 46.
`
Prevention
- Monitor worker utilization via
server-statusand alert when usage exceeds 80% - Use
aborwrkto load test and determine the optimal MaxRequestWorkers for your hardware - Consider switching from
mpm_preforktompm_eventwith PHP-FPM for better concurrency - Implement request timeout limits:
Timeout 60andProxyTimeout 120to prevent slow requests from monopolizing workers - Use a reverse proxy (Nginx, HAProxy) in front of Apache to queue requests instead of dropping them
- Add
MaxConnectionsPerChildto prevent memory leaks from long-running processes