Course contentsShow
← Node.js
Lesson 1911 of 1,98017. Performance Tuning and ProfilingFree lesson

Differentiating Total vs Self Time in Profiles

You will evaluate whether a function's cost comes from itself or its children in the call tree.

In this lesson, you will learn how to distinguish between the time a function spends executing its own logic versus the time it spends waiting for the functions it calls to complete.

When analyzing CPU profiles or flame graphs, understanding the difference between Total Time and Self Time is the difference between finding a bottleneck and chasing a ghost.

The Definitions

  • Total Time: The cumulative time a function spent running, including the time spent inside all functions it invoked. If function A calls function B, the time spent in B is included in the Total Time of A.
  • Self Time: The time a function spent executing its own instructions, excluding any time spent waiting for child function calls to finish.

Why it Matters

Consider this typical scenario:

function processData(items) {
  // Self Time: Heavy regex calculation here (e.g., 50ms)
  validateItems(items); // Total Time: 400ms (Child call)
  formatOutput(items);  // Total Time: 50ms (Child call)
}

If you look at processData in a profiler, its Total Time is 500ms. However, if you only optimize processData by simplifying its internal code, you might only reclaim that 50ms of Self Time. The majority of the cost (400ms) is actually hidden inside validateItems.

If the Flame Graph for processData is very wide, but its "Self Time" is thin, it means the function is simply a "traffic cop"—it is not the root cause of your performance issue. You must traverse down the call stack to the child functions that occupy the widest horizontal space to find the true source of your latency.

By focusing on functions where Self Time is high, you identify code that is computationally expensive on its own (like loops, regex, or serialization). By focusing on functions where Total Time is high but Self Time is low, you are likely looking at a function that is simply managing too many expensive sub-tasks.

Key Takeaway: Always check if a function's high Total Time is inherited from its children; if Self Time is low, your optimization efforts should be directed at the children, not the parent.