# Profiling flows with ClinicJs to analyze CPU performance issues

**URL:** <https://discourse.nodered.org/t/profiling-flows-with-clinicjs-to-analyze-cpu-performance-issues/55139>\
**Category:** Share Your Projects\
**Created:** [13 December 2021 22:02 UTC](https://discourse.nodered.org/t/profiling-flows-with-clinicjs-to-analyze-cpu-performance-issues/55139 "2021-12-13T22:02:10Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [13 December 2021 22:02 UTC](https://discourse.nodered.org/t/profiling-flows-with-clinicjs-to-analyze-cpu-performance-issues/55139/1 "2021-12-13T22:02:10Z")

</div>

Hi folks,

Last week I started a [discussion](https://discourse.nodered.org/t/cpu-profiling-a-single-node-collecting-ideas/55012/) to collect ideas whether it is possible to build a - in the future - Node-RED profiler (to find which nodes consume lots of system resources like cpu/ram). However Nick had a very fair point that a lot of nodes will do their heavy processing asynchronously, so from that point there is no relation anymore between the node and the system resources it uses. Indeed a node can use system resources:

- By code that is being executed synchronous (i.e. directly called inside the node)
- By code that is being executed asynchronous (i.e. in the background by the NodeJs event loop)

While I was looking for a solution to this problem, I came across [ClinicJs](https://clinicjs.org/). In my opinion, the ClinicJs BubbleProf tool can be very useful to profile a Node-RED flow. Because BubbleProf groups together asynchronous operations in "bubbles", and measures cpu times for each of those groups. By doing it that way, _ **the nodes of your flow will be mapped to bubbles** _.

I will "try" to explain step by step how to use ClinicJs for cpu profiling of your flow.

## Analyze which node(s) consume high cpu - bubbles of asynchronous functions

1. Start Node-RED via ClinicJs, so it can inject profiling code into NodeJs:

2. ClinicJs will immediately add an extra line at the top of the Node-RED log:

3. Now execute the actions in Node-RED which result into your performance issue. In my case things are becoming really slow when I inject a message into this flow, which contains a few nodes that I am developing at the moment:

4. As soon as you are done, press Crtl-C in your shell window. This will stop Node-RED and the profiling analysis will automatically start:

5. The generated html file will automatically be opened in a browser window, and shows your profiling result as bubbles:

6. When hoovering above the bubble of my PolygonTransformationNode, you will see this popup:

7. When you click this node, the corresponding async stack trace will be displayed:

Ok so now I know that my PolygonTransformNode is responsible for the high cpu.

## Analyze which part of a node consumes high cpu - flames of synchronous functions

But I also would like to have a look which of the synchronous actions inside my PolygonTransformNode is consuming all that cpu. My experience with ClinicJs is limited to about 20 minutes ( 😌), so I don't know if you can navigate from the bubbles directly to this information. So I will use another tool to profile the synchronous actions:

1. I press Ctrl-C again in my shell window, to close Node-RED completely.

2. Start Node-RED via ClinicJs again, but now with the _ **Flame** _ application:

3. Repeat the test again in the flow.

4. After pressing CTRL-C again (twice), the generated html will be opened in a browser window automatically.

5. The html will contain this time a _ **flame chart** _:

## Summary

Although ClinicJs is a very nice tool, I am aware that it has a number of disadvantages:

- There is no memory profiling. So you will still need other profiling tools, e.g. Chrome developer tools.
- You need external tools, since there is no integration into Node-RED. Which makes it very cumbersome to use...
- You need to change your startup command, which is not always easy (e.g. in Docker).
- It is a pitty that the bubble and flame charts are not integrated into a single tool. Would have been nice if the related asynchronous and synchronous profiling had been combined.
- You need to stop Node-RED to start the analysis. So no live profiling by attaching the profiler to a running Node-RED instance.

This is the first time that I have used ClinicJs, so I am absolutely _ **NO** _ expert. If you find other useful stuff in this tool, please share it here with us! And if you have found other similar/better tools, please create a separate discussion and share the link to it here (to keep this discussion focussed on ClinicJs).

Although the literature is quite heavy to read, I hope it can help you troubleshoot your performance issues a bit more scientifically based...

Bart

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [13 December 2021 22:43 UTC](https://discourse.nodered.org/t/profiling-flows-with-clinicjs-to-analyze-cpu-performance-issues/55139/2 "2021-12-13T22:43:32Z")

</div>

> [@BartButenaers](#):
>
> But of course the startup code of Node-RED consumes a lot of cpu compared to my little test sequence, so those bubbles will be bigger in such short tests...

When I do some more tests (by injecting) more messages into my problematic flow, then the profiler will be able to collect much more issue-related information. And then the results becomes more interesting, because _ **my Node-RED flow becomes visible in the bubbles** _:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/f/bf528cdf6d84dfdb823aeca5b8c8c5ca9daa2a1f.png)

a. The 'server' bubble is becoming smaller, because my test has been consuming more percentage of the cpu (used during the analysis time frame).

b. First my PolygonTransformationNode is being called, which consumes quite some cpu.

c. From that node there is a connection to my next node in the flow (the ImageAnnotationVisualizerNode), which means the wire (between two Node-RED nodes) is becoming visible as a connection (between two bubbles).

d. A longer connection means that there is more latency between two bubbles.

Although I have to be honest that I don't succeed in showing my second node as a bubble in all my tests. Need a bit more experience with the tool, before I can explain such things...

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [13 December 2021 23:12 UTC](https://discourse.nodered.org/t/profiling-flows-with-clinicjs-to-analyze-cpu-performance-issues/55139/3 "2021-12-13T23:12:14Z")

</div>

And a last test for today. I have added in my "input" message handler (of my PolygonTransformationNode), both an _ **async function** _ and a _ **promise** _:

```auto
node.on("input", function(msg) {
   async function asyncCall() {
       new Promise(resolve => {
           // My bad performance code has now moved here
       });
   }

   asyncCall();            
});

```

Fortunately ClinicJs can still group all those async actions together in my PolygonTransformationNode bubble async call stack:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/1/f1bdb70b47121f09af9d51facac0e29e07aaaa86.png)

The [async-hooks](https://nodejs.org/api/async_hooks.html#async-hooks) NodeJs module (used by ClinicJs under the cover) seem to be quite useful for me, in the context of profiling a Node-RED flow.

But if anybody has some doubts about this, or if I have forgotten something important, please share your thoughts here! Because chances are pretty high that I have overlooked something ...
