Translate: 
EnglishFrenchGermanItalianPolishPortugueseRussianSpanish

How to calculate CPU usage of a PHP script

There are many PHP scripts that calculate it’s execution time, memory usage and even the number of queries sent to databases.

All of these indicators are extremely important when testing the code to optimize it later. For me, however, there is still one parameter missing: the percentage of time the processor spends on execution of the PHP script itself!

Solution

In most cases, the calculation is very simple. Just use the built-in getrusage() function:

<?php
 
function onRequestStart() {
	$dat = getrusage();
	define('PHP_TUSAGE', microtime(true));
	define('PHP_RUSAGE', $dat["ru_utime.tv_sec"]*1e6+$dat["ru_utime.tv_usec"]);
}
 
function getCpuUsage() {
    $dat = getrusage();
    $dat["ru_utime.tv_usec"] = ($dat["ru_utime.tv_sec"]*1e6 + $dat["ru_utime.tv_usec"]) - PHP_RUSAGE;
    $time = (microtime(true) - PHP_TUSAGE) * 1000000;
 
    // cpu per request
    if($time > 0) {
        $cpu = sprintf("%01.2f", ($dat["ru_utime.tv_usec"] / $time) * 100);
    } else {
        $cpu = '0.00';
    }
 
    return $cpu;
}
 
?>

Instruction for this script is fairly simple. You have to call the onRequestStart() function during the start of application. Then later in the code you can call the getCpuUsage() function any time you want to get the current CPU usage of your program (preferably you should do this by the end of the script).

Summary

As I’ve already said this works in most cases. Infamous exception is, of course, Windows, for which the function was not implemented. When you use this script in mixed Windows/Linux environments you should implement alternative code paths and ignore this CPU check if necessary.

4 Responses to “How to calculate CPU usage of a PHP script”

  1. Andrei says:

    Hello,

    I’ve used this code (thank you for sharing it) to test the cpu usage on a website’s homepage.
    That homepage is pretty big, with lots of texts and pictures displayed and many “latest-items” or “random-items” pulled from database.
    The site is using php and mysql.

    With this snippet I’m getting a cpu usage of 6 – 13, depending on how fast I refresh the page. If I refresh the pages faster, I get lower CPU, if I refresh it at bigger time intervals, I get higher CPU usage.

    Can you tell me what your opinion on this data and wheater it’s normal or too much for a (heavy-loaded) homepage to consume that kinda cpu power?

    Btw, I’m on a 2 cores VPS with 512M ram.

  2. Artur Graniszewski says:

    Please remember, that low CPU usage reported by this snipet does not mean that your servers are idle.

    For example, your page may load for more than 2 seconds, but take only 2% of CPU. How is it possible? It’s simple – 2% are eaten by the PHP, while another 98% by the MySQL server or some server side locks (like IO/network bottlenecks).

    To measure the performance of your webpage, you have to take at least two different variables into account: combined CPU usage (PHP + MySQL) and a page load time (a good ratio of requests per second).
    Even if your script eats only 1% of CPU, but works for 3 seconds, this can become a major problem (a domino effect), on a busy site, because you will quickly achieve 200 active PHP processes (with combined 100% CPU usage). In best case scenario you want to have fast load times and low CPU usage.

    Definitively you want to avoid long page loads and low CPU usage – this could mean some serious hardware problems/bottlenecks.

  3. Brain Teaser says:

    Getting Values > 100

  4. Artur Graniszewski says:

    There is one case, when CPU load can be higher than 100%. You can ovserve this situation, when launching ultra fast PHP scripts (which run for less than few microseconds). In some OS’s time returned by a microtime() function is more accurate than from getrusage(). Because of this, getrusage() can report elapsed time as 0.3333333ms while microtime will tell you, that the real time is 0.0021ms. In this case, ignore the false cpu usage, and report it as 100%.

Leave a Reply