Search code examples
node.jsexpresscpu-usagenode-mysql

Node.js high CPU usage, how to debug it?


I've an app made with Node.js + Express 3 + Jade that use MySQL DB and node-mysql module.

The app is started and monitored by PM2.

When main page is loaded I see a very high use of CPU as in the follow picture.

usage of CPU of App Node.js

The start page performs three queries on a MySQL DB, but also if I put Json objects instead of MySQL queries, it seems CPU usage is still too high.

There is a way to track the CPU usage into the endpoint function to understand the reason of high usage of CPU?


Solution

  • I solved my CPU issue thanks profiling.

    I tried to log the CPU usage in more parts of my endpoint function, but this approach it wasn't helpful. For everyone who need get the CPU usage this script it's very good: http://gist.github.com/bag-man/5570809

    To exclude that the issue was related to MySQL queries I create a simple app that performed only queries and I tested it with ApacheBench. This test was passed successfully.

    After that I found the solution.

    Profiling for Node.js it's explained here: https://nodejs.org/en/docs/guides/simple-profiling/

    I ran the app with the built in profiler:

    NODE_ENV=development node --prof app.js
    

    I made some requests by ApacheBench

    ab -k -c 20 -n 250 "http://localhost:8080/"
    

    I generated a processed.txt

    node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt
    

    In the summary I got that:

     [Summary]:
       ticks  total  nonlib   name
        4036   22.6%   23.3%  JavaScript
       13130   73.6%   75.9%  C++
        1334    7.5%    7.7%  GC
         527    3.0%          Shared libraries
         144    0.8%          Unaccounted
    

    The "Bottom up (heavy) profile" was all related to the uglify-js module:

    /node_modules/with/node_modules/uglify-js/lib/parse.js
    

    So looking the dependencies I saw that this module is used by Jade.

    My app performed a lot of queries and generate a large Json object that it was passed to the Jade template engine.

    The Jade used a lot of CPU to parse the large object passed.

    As first I made an update of that module from 0.35.0 to 1.3.1 (because pug is still in alpha).

    Jade used a lot of CPU to parse the large object passed.

    As first I made an update of that module from 0.35.0 to 1.3.1 (because pug is still in alpha).

    Thanks to this update, performances increased.

    But finally I plan to load the page without heavy queries and get the needed information by a REST service, without passing data to Jade