Current Location: Home> Latest Articles> How to Use getrusage() to Monitor System Load Changes Before and After Database Queries to Improve Performance?

How to Use getrusage() to Monitor System Load Changes Before and After Database Queries to Improve Performance?

M66 2025-06-11

What is getrusage()

getrusage() is a native PHP function used to retrieve resource usage information for the current process or its child processes. It returns an array containing multiple system-level data points, such as user and system CPU time, the number of memory page faults, and context switch counts.

$usage = getrusage();

Some commonly used fields include:

  • ru_utime.tv_sec and ru_utime.tv_usec: time spent in user mode (seconds and microseconds)

  • ru_stime.tv_sec and ru_stime.tv_usec: time spent in system mode (seconds and microseconds)

  • ru_minflt: number of page faults not requiring disk access (soft faults)

  • ru_majflt: number of page faults that required disk access (hard faults)

  • ru_nvcsw and ru_nivcsw: counts of voluntary and involuntary context switches


Calling getrusage() Before and After Database Queries

To monitor the impact of database queries on the system, the most straightforward approach is:

  1. Record getrusage() before the query;

  2. Execute the query;

  3. Record getrusage() again after the query;

  4. Compare the difference between the two recordings.

Example code is as follows:

function getResourceUsageDiff($start, $end) {
    $diff = [];
    foreach ($end as $key => $value) {
        if (isset($start[$key])) {
            $diff[$key] = $value - $start[$key];
        }
    }
    return $diff;
}
<p>$before = getrusage();</p>
<p>// Simulate a database query<br>
$mysqli = new mysqli("localhost", "user", "password", "database");<br>
$result = $mysqli->query("SELECT * FROM users WHERE email LIKE '%@example.com'");</p>
<p>$after = getrusage();</p>
<p>$usageDiff = getResourceUsageDiff($before, $after);</p>
<p>echo "<pre>";<br>
print_r($usageDiff);<br>
echo "
";

This code outputs the system resource changes caused by the query. For example, if you see a noticeable increase in ru_stime.tv_usec, it indicates the query caused an increase in system CPU time, which may imply heavy I/O operations.


A More Intuitive Display: Function Encapsulation and Logging

For practical use, you can encapsulate the measurement process into a function that automatically logs the query statement and resource changes:

function profileQuery($query, $mysqli) {
    $before = getrusage();

$after = getrusage();
$usageDiff = getResourceUsageDiff($before, $after);

file_put_contents("/var/log/db_profile.log", json_encode([
    'query' => $query,
    'usage' => $usageDiff,
    'time'  => date('c')
]) . PHP_EOL, FILE_APPEND);

return $result;

}

This approach lets you continuously collect data on how queries impact system resources without interfering with normal logic, providing a solid basis for future optimization.


Practical Application Suggestions

  1. Compare the Impact of Different Index Structures
    Using the same conditions with different indexing strategies, compare system resource usage to intuitively evaluate the effectiveness of index adjustments.

  2. Monitor Performance of Bulk Queries or Large Data Pagination
    When handling pagination or bulk queries, watch for increases in ru_majflt and ru_nvcsw to determine whether queries trigger excessive memory paging or context switching.

  3. Compare Resource Usage in Stress Testing
    Combine with tools like Apache Benchmark or JMeter for concurrent testing, record resource usage changes, and analyze system behavior under high load.


Bonus: Beautify Output (For Debugging)

If you want to see getrusage() changes more clearly in your browser during debugging, you can use the following code to format the output:

function formatUsage(array $usage) {
    return sprintf(
        "User CPU: %.4fs, System CPU: %.4fs, Major Faults: %d, Voluntary CS: %d",
        $usage['ru_utime.tv_sec'] + $usage['ru_utime.tv_usec'] / 1e6,
        $usage['ru_stime.tv_sec'] + $usage['ru_stime.tv_usec'] / 1e6,
        $usage['ru_majflt'] ?? 0,
        $usage['ru_nvcsw'] ?? 0
    );
}
<p data-is-last-node="" data-is-only-node="">echo formatUsage($usageDiff);<br>