Skip to content

Instantly share code, notes, and snippets.

@bag-man
Last active March 29, 2024 12:01
Show Gist options
  • Star 70 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save bag-man/5570809 to your computer and use it in GitHub Desktop.
Save bag-man/5570809 to your computer and use it in GitHub Desktop.
How to calculate the current CPU load with Node.js; without using any external modules or OS specific calls.
var os = require("os");
//Create function to get CPU information
function cpuAverage() {
//Initialise sum of idle and time of cores and fetch CPU info
var totalIdle = 0, totalTick = 0;
var cpus = os.cpus();
//Loop through CPU cores
for(var i = 0, len = cpus.length; i < len; i++) {
//Select CPU core
var cpu = cpus[i];
//Total up the time in the cores tick
for(type in cpu.times) {
totalTick += cpu.times[type];
}
//Total up the idle time of the core
totalIdle += cpu.times.idle;
}
//Return the average Idle and Tick times
return {idle: totalIdle / cpus.length, total: totalTick / cpus.length};
}
//Grab first CPU Measure
var startMeasure = cpuAverage();
//Set delay for second Measure
setTimeout(function() {
//Grab second Measure
var endMeasure = cpuAverage();
//Calculate the difference in idle and total time between the measures
var idleDifference = endMeasure.idle - startMeasure.idle;
var totalDifference = endMeasure.total - startMeasure.total;
//Calculate the average percentage CPU usage
var percentageCPU = 100 - ~~(100 * idleDifference / totalDifference);
//Output result to console
console.log(percentageCPU + "% CPU Usage.");
}, 100);
@adamyanalunas
Copy link

You're tracking ticks across all cores but totaling their average. That doesn't seem right. cpuAverage should probably take a core number as an argument so it can be used to average load per core.

cpuAverage will eventually overflow totalIdle and totalTicks. You should look into limiting those on a one-time (yuck) or continual (yay!) basis.

@four43
Copy link

four43 commented Oct 31, 2014

For others who landed here via Google search: Node now has a os.loadavg() method you can find at: http://nodejs.org/api/os.html#os_os_loadavg Which is much simpler.

@schifferl
Copy link

Both of the above comments miss the point of this gist entirely... totalTick is divided by cpus.length (i.e. the number of cpus) and os.loadavg() will give the average load not the instantaneous... Excellent gist, just need to understand what you are looking at

@yassine-khachlek
Copy link

Hi, thanks for the trick, i have just to notice that start Measure variable should be updated after calculating the percentage CPU so we can get the percentage CPU for the last time interval, in your case 100 milliseconds. the actual code is calculating the percentage CPU for all the time the device is up and it's wrong.

Have just to add :
startMeasure = cpuAverage();
after line 43:
var percentageCPU = 100 - ~~(100 * idleDifference / totalDifference);

@SuperPaintman
Copy link

I rewrite it like closure function:

os = require 'os'

cpuAverage = ->
    totalIdle = 0
    totalTick = 0

    cpus = os.cpus()

    for cpu in cpus
        for type of cpu.times
            totalTick += cpu.times[type]

        totalIdle += cpu.times.idle

    idle    = totalIdle / cpus.length
    total   = totalTick / cpus.length

    return {
        idle
        total
    }

###*
 * @return {Object} dif - difference of usage CPU
 * @return {Float}  dif.idle
 * @return {Float}  dif.total
 * @return {Float}  dif.percent
###
cpuLoadInit = =>
    start = cpuAverage()
    return ->
        end = cpuAverage()
        dif = {}

        dif.idle  = end.idle  - start.idle
        dif.total = end.total - start.total

        dif.percent = 1 - dif.idle / dif.total

        return dif

cpuLoad = cpuLoadInit()

module.exports = {
    cpuAverage
    cpuLoad
}

Usage:

cpu = require './lib/cpu.js'

load = cpu.cpuLoad()
console.log load
###
{
  idle: 71429,
  percent: 0.09731516059118284,
  total: 79129.5
}
###

@astroza
Copy link

astroza commented Jan 10, 2017

If you need integrate this in your application to get the average load in the past X milliseconds:

function CPULoad(avgTime, callback) {
  this.samples = [];
  this.samples[1] = cpuAverage();
  this.refresh = setInterval(() => {
    this.samples[0] = this.samples[1];
    this.samples[1] = cpuAverage();
    var totalDiff = this.samples[1].total - this.samples[0].total;
    var idleDiff = this.samples[1].idle - this.samples[0].idle;
    callback(1 - idleDiff / totalDiff);
  }, avgTime);
}

// load average for the past 1000 milliseconds
var load = CPULoad(1000, (load) => console.log((100*load).toFixed(1)));

@loretoparisi
Copy link

I have slightly modified this script to get the average load for a single cpu

cpuIAverage = function(i) {
  var cpu, cpus, idle, len, total, totalIdle, totalTick, type;
  totalIdle = 0;
  totalTick = 0;
  cpus = os.cpus();
  cpu = cpus[i];
  for (type in cpu.times) {
    totalTick += cpu.times[type];
  }
  totalIdle += cpu.times.idle;

  idle = totalIdle / cpus.length;
  total = totalTick / cpus.length;
  return {
    idle: idle,
    total: total
  };
};

and

cpuILoadInit = function() {
  var index=arguments[0];
  return function() {
    var start;
    start = cpuIAverage(index);
    return function() {
      var dif, end;
      end = cpuIAverage(index);
      dif = {};
      dif.cpu=index;
      dif.idle = end.idle - start.idle;
      dif.total = end.total - start.total;
      dif.percent = 1 - dif.idle / dif.total;
      return dif;
    };
  };
};

where

cpuILoad = (function() {
  var info=[],cpus = os.cpus();
  for (i = 0, len = cpus.length; i < len; i++) {
    var a=cpuILoadInit(i)();
    info.push( a );
  }
  return function() {
    var res=[],cpus = os.cpus();
    for (i = 0, len = cpus.length; i < len; i++) {
      res.push( info[i]() );
    }
    return res;
  }

})();

I think it's easier than this, but it should print on a i7:

> cpu.cpuILoad()
[ { cpu: 0,
    idle: 148.75,
    total: 1103.75,
    percent: 0.8652321630804077 },
  { cpu: 1,
    idle: 797.5,
    total: 1103.75,
    percent: 0.2774631936579841 },
  { cpu: 2,
    idle: 142.5,
    total: 1102.5,
    percent: 0.8707482993197279 },
  { cpu: 3,
    idle: 798.75,
    total: 1102.5,
    percent: 0.2755102040816326 },
  { cpu: 4,
    idle: 146.25,
    total: 1102.5,
    percent: 0.8673469387755102 },
  { cpu: 5, idle: 795, total: 1102.5, percent: 0.2789115646258503 },
  { cpu: 6,
    idle: 142.5,
    total: 1102.5,
    percent: 0.8707482993197279 },
  { cpu: 7,
    idle: 796.25,
    total: 1101.25,
    percent: 0.27695800227014755 } ]

@aetheryx
Copy link

So this script seems to loop through all of the cores. Is it possible to shorten it in such a way that it only reads the first core? I'm running on a 1-core VPS, so I don't think there's any advantage for me to run through all cores.

@luokuning
Copy link

Here is a way that console every single cpu average load:

const os = require('os')

function delta() {
  const cpus = os.cpus()

  return cpus.map(cpu => {
    const times = cpu.times
    return {
      tick: Object.keys(times).filter(time => time !== 'idle').reduce((tick, time) => { tick+=times[time]; return tick }, 0),
      idle: times.idle,
    }
  })
}

let startMeasures = delta()
setInterval(() => {
  const endMeasures = delta()
  const percentageCPU = endMeasures.map((end, i) => {
    return ((end.tick - startMeasures[i].tick) / (end.idle - startMeasures[i].idle) * 100).toFixed(3) + '%'
  })

  console.log(percentageCPU.join(' '), '\n')

  // reset
  startMeasures = delta()
}, 2000)

@OussamaRomdhane
Copy link

OussamaRomdhane commented Mar 8, 2018

Hi mate, great gist.
This line of code though seems a bit ambiguous to me:
https://gist.github.com/bag-man/5570809#file-cpu-js-L43
I get that you're trying to get rid of the fractional-part but couldn't you just use Math.floor or Math.rand? I say that only for readability/maintainability reasons.

@adrwh
Copy link

adrwh commented Dec 14, 2018

Noob <, however how can i use this with chart.js?

@GaetanoPiazzolla
Copy link

GaetanoPiazzolla commented Nov 8, 2019

Here is a way to get the medium load every N milliseconds, checking the load every M milliseconds.
Also, I've used promise style asynch programming.
https://gist.github.com/GaetanoPiazzolla/c40e1ebb9f709d091208e89baf9f4e00

@aggregate1166877
Copy link

aggregate1166877 commented Aug 27, 2020

I rewrite it like closure function:

That looks damn beautiful - but I can't get it to work. What's that style called? What kind of processor / compiler do you need for that?

@GaetanoPiazzolla
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment