How to Diagnose and Fix High CPU Usage in PHP Processes: A Step‑by‑Step Guide
This article walks through a real‑world incident where a PHP service consumed over 80% CPU, detailing how to identify the offending processes with htop, examine their status, trace system calls with strace, inspect file descriptors via lsof, and ultimately locate and correct a looping SQL query that caused the overload.
Background
The weekend deployment showed a white‑screen for users, and monitoring revealed an abnormally high CPU usage by a PHP process, despite low expected traffic. The team suspected a dead loop in the PHP code.
Investigation Steps
Step 1 – Check CPU/Memory with htop
Running htop and sorting by memory (Shift + M) highlighted the top two CPU‑hungry processes, both belonging to the service http://0.0.0.0:8782 RestyService, each consuming about 81.2% CPU (PIDs 17472 and 17487).
Step 2 – View Process Status
Executing php start.php status showed that processes [17487] and [17475] were in a busy state, indicating continuous work rather than idle.
A persistent busy state can mean business blockage or an infinite loop; idle would indicate normal operation.
Step 3 – Debug the Busy Process
If a process stays busy without returning to idle, the underlying business logic is likely blocked or looping. The PID of the busy process (e.g., 17487) becomes the focus for deeper inspection.
Step 4 – Trace System Calls with strace
Running sudo strace -ttp 17487 displayed repeated poll([{fd=9, events=… calls, showing the process waiting on file descriptor 9.
Note: If no system calls appear, open a new terminal and send kill -SIGALRM 17487 to trigger a response; lack of output suggests a business‑level infinite loop.
Step 5 – Inspect File Descriptors with lsof
Using lsof -p 17487 | grep 9 revealed that fd 9 corresponds to a TCP connection to 172.18.207.82:mysql, indicating the process was waiting for a database response.
ping rm-xxxxxxxxxxx.mysql.rds.aliyuncs.com
PING rm-xxxxxxxxxxx.mysql.rds.aliyuncs.com (172.18.207.82) 56(84) bytes of data.
64 bytes from 172.18.207.82: icmp_seq=1 ttl=102 time=1.93 ms
...The high CPU was thus traced to a loop continuously polling the database.
Step 6 – Locate the Looping SQL
Further analysis identified a while loop that repeatedly executed the following SQL statement:
SELECT `id` FROM `sg_organ_xxx` WHERE `id` = 2025Strace showed the process repeatedly issuing a sendto on fd 9 with this query, confirming the infinite loop.
Verification
After removing the while loop and redeploying, the team re‑checked CPU and memory usage; the PHP process returned to normal levels ( ~0% CPU).
Conclusion
Performance problems can be hidden and only surface under load. Developers should continuously monitor resource usage, employ tools like htop, strace, and lsof to pinpoint bottlenecks, and review code for inefficient loops or database queries. Proactive testing and disciplined coding practices help prevent such CPU spikes and ensure stable, responsive applications.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
