Skip to content

Instantly share code, notes, and snippets.

@bag-man bag-man/cpu.js
Last active Jul 12, 2019

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

commented May 14, 2013

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented May 11, 2015

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

This comment has been minimized.

Copy link

commented Sep 27, 2015

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

This comment has been minimized.

Copy link

commented Oct 12, 2015

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Mar 13, 2017

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

This comment has been minimized.

Copy link

commented Jul 17, 2017

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

This comment has been minimized.

Copy link

commented Aug 30, 2017

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

This comment has been minimized.

Copy link

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.

@ajhstn

This comment has been minimized.

Copy link

commented Dec 14, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.