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.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
How to Diagnose and Fix High CPU Usage in PHP Processes: A Step‑by‑Step Guide

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` = 2025

Strace 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DebuggingLinuxPHPCPUstracehtop
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.