Scenario
A production web server (running Nginx and PHP-FPM) for an e-commerce platform suddenly experiences high CPU load. User response time increases from 200ms to over 5 seconds, and some requests time out.
Symptoms
topshows CPU usage >95% sustained, with user space at 80%.uptimeload average exceeds 2x the number of CPU cores (16 cores).- Nginx logs show many 504 Gateway Timeout errors.
- Application monitoring indicates PHP-FPM processes reached max limit.
Diagnosis Steps
- Identify resource bottleneck: Run
top, sort by CPU (P), observe multiple PHP-FPM processes consuming high CPU. - Trace system calls: Use
strace -p <PID> -c -S timeto identify time-consuming syscalls; found heavyepoll_waitandrecvfrom. - Performance sampling:
perf top -p <PID>reveals hot functions inphp:--likeexecute_exand Zend engine functions. - Check slow logs: Examine PHP-FPM slow log (
slowlog) reveals multiple requests taking >30 seconds, all calling an external API. - Network analysis:
netstat -anp | grep :80shows many TIME_WAIT connections but not hitting limits.
Commands Used
# Monitor CPU usage
watch -n 1 'ps aux --sort=-%cpu | head -20'
# Trace process syscalls
strace -fp $(pgrep -d',' php-fpm) -c -S time 2>&1 | head -30
# Profile hot spots
perf top -p $(pgrep -d',' php-fpm)
# Check slow log
tail -f /var/log/php-fpm/slow.log
# Count network connections
ss -tan | awk '{print $1}' | sort | uniq -c
Risk Controls
- Before diagnosis, ensure monitoring alerts and rollback capability exist (e.g., blue-green deployment or quick restart script).
- Run
straceduring low traffic to avoid overhead. - Use
timeoutfor dangerous commands:timeout 10 strace .... - Avoid
kill -9on production; preferkill -TERMor systemd stop.
Rollback Operations
- If caused by new code, rollback to previous stable version:
git revert <commit> && systemctl restart php-fpm nginx. - If external API timeout, temporarily reduce Nginx
proxy_read_timeoutfrom 30s to 5s and enable circuit breaker. - If PHP-FPM processes are out of control, kill all children and restart:
bash systemctl stop php-fpm killall -9 php-fpm # only if normal stop fails systemctl start php-fpm
Verification
- Use
aborwrkto simulate requests:wrk -t4 -c100 -d30s http://localhost/, observe response time and error rate. - Check CPU usage returns to normal (<60%).
- Confirm no 504 errors in logs.
- Verify user-reported latency is back to baseline.
When to Submit an OpsGlobal Ticket
- Issue persists >30 minutes and root cause is unclear.
- Requires cross-team coordination (e.g., database or network team).
- High-risk operations (e.g., kernel tuning) needed with low confidence.
- Data loss or complete service outage (submit emergency ticket immediately).
- Need post-mortem assistance or second opinion to improve runbook.
Use cases
Useful for teams handling DevOps issues and needing a clear troubleshooting and delivery workflow.
Problem background
A practical guide on diagnosing and resolving a high CPU load issue on a production web server, following the SRE runbook structure: scenario, symptoms, diagnosis, risk controls, rollback, verification, and when to escalate to OpsGlobal.
Troubleshooting steps
Confirm impact and recent changes, collect logs, configuration and metrics, then apply fixes from low to high risk.
Command examples
Replace sample resource names with real values and store passwords, tokens and keys in environment variables.
Risks
Before production changes, confirm backups, access boundaries, change windows and rollback paths.
Rollback plan
Keep original configuration and release versions; roll back config, images or database changes if metrics degrade.
Deliverables
Root-cause notes, key commands, remediation steps, verification results and follow-up recommendations.
Need help with a similar technical issue?
If your servers, Kubernetes, Docker, CI/CD, databases or monitoring systems have similar issues, submit logs and config files for remote diagnosis.