Fixing Apache High CPU Usage (httpd 100% CPU)
Resolve Apache high CPU usage by tuning MaxRequestWorkers, enabling KeepAlive, mitigating DDoS attacks, and fixing runaway PHP scripts.
- Misconfigured MPM (Multi-Processing Module) settings often lead to resource exhaustion.
- Runaway PHP scripts or slow database queries can block Apache workers and spike CPU.
- Traffic spikes, bad bots, or DDoS attacks can quickly overwhelm the server.
- Use top, htop, and apachectl status to identify the root cause immediately.
| Method | When to Use | Time | Risk |
|---|---|---|---|
| Tuning MPM Prefork/Event | Server is overloaded during normal traffic peaks | 15 mins | Low |
| Enabling/Tuning KeepAlive | High volume of requests for static assets | 5 mins | Low |
| Blocking Bad Bots (fail2ban/iptables) | Suspicious traffic patterns or DDoS attempts | 20 mins | Medium |
| Optimizing Backend (PHP-FPM/MySQL) | Database queries or scripts are slow | Hours | High |
Understanding the Error
Apache high CPU usage is typically characterized by the httpd or apache2 processes consuming close to 100% of the CPU resources. This can lead to slow response times, 502 Bad Gateway, or 504 Gateway Timeout errors for your users. The root cause usually falls into one of three categories: traffic spikes (legitimate or malicious), inefficient backend processing (like slow PHP scripts or database queries), or misconfigured Apache settings that fail to handle concurrency efficiently.
When you run top or htop, you might see multiple apache2 or httpd processes dominating the CPU column. This happens because Apache spawns child processes or threads to handle incoming connections. If these connections take too long to process (due to slow backend responses) or if there's a flood of connections, the server maxes out its processing power.
Step 1: Diagnose the Root Cause
Before making changes, you need to understand what Apache is actually doing.
1. Check Server Status with apachectl
Ensure mod_status is enabled. Run apachectl status or apachectl fullstatus to see what requests are currently being processed, the state of all workers, and how long they've been running. Look for workers stuck in the 'W' (Sending Reply) or 'R' (Reading Request) states for unusually long times.
2. Identify the Culprit Process
Use top -c to see the full command line of the processes. If you are using PHP as an Apache module (mod_php), the Apache process itself will consume the CPU. If you are using PHP-FPM, you might see php-fpm processes spiking alongside Apache.
3. Analyze Access Logs
Check your access logs (/var/log/apache2/access.log or /var/log/httpd/access_log) for unusual traffic patterns. Use awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -n 10 to find the IP addresses making the most requests.
Step 2: Fix Misconfigurations
1. Tune the Multi-Processing Module (MPM)
Most modern Apache installations use the Event or Worker MPM, which are much more efficient than Prefork. If you must use Prefork (e.g., for mod_php), ensure MaxRequestWorkers is not set too high. If it's higher than what your RAM can support, the server will swap to disk, drastically increasing CPU wait times. Calculate the average RAM used by an Apache process and divide your total available RAM by that number to find a safe MaxRequestWorkers value.
2. Enable and Configure KeepAlive
If KeepAlive is off, Apache must open a new connection for every single asset (image, CSS, JS) on a page. This incurs significant CPU overhead. Turn KeepAlive On in your apache2.conf or httpd.conf, but keep MaxKeepAliveRequests high (e.g., 100) and KeepAliveTimeout low (e.g., 2 to 5 seconds) to prevent idle connections from tying up workers.
Step 3: Mitigate Malicious Traffic
If your logs show a flood of requests from specific IPs or unusual user agents, you might be under a minor DDoS attack or scraping bot assault.
1. Block IPs using iptables or ufw Use the firewall to block abusive IPs outright before they reach Apache.
2. Implement fail2ban Configure fail2ban to monitor your Apache access and error logs and automatically ban IPs that exhibit malicious behavior, such as repeatedly requesting nonexistent files (404s) or brute-forcing login pages.
Frequently Asked Questions
# 1. Check current Apache connections by IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
# 2. View active requests and worker status (requires mod_status)
apachectl fullstatus
# 3. Find top 10 IPs hitting the server today
awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -n 10
# 4. Example MPM Event configuration tuning (/etc/apache2/mods-available/mpm_event.conf)
# <IfModule mpm_event_module>
# StartServers 2
# MinSpareThreads 25
# MaxSpareThreads 75
# ThreadLimit 64
# ThreadsPerChild 25
# MaxRequestWorkers 150
# MaxConnectionsPerChild 0
# </IfModule>Error Medic Editorial
Expert system administrators and Site Reliability Engineers dedicated to providing actionable, real-world solutions for complex server infrastructure issues.