debug profile for debug

Profile pipeline elements in a closure.


> debug profile {flags} (closure)


  • --spans, -s: Collect spans of profiled elements
  • --expand-source, -e: Collect full source fragments of profiled elements
  • --values, -v: Collect pipeline element output values
  • --expr, -x: Collect expression types
  • --instructions, -i: Collect IR instructions
  • --lines, -l: Collect line numbers
  • --max-depth, -m {int}: How many blocks/closures deep to step into (default 2)


  • closure: The closure to profile.

Input/output types:



Profile config evaluation

> debug profile { source $nu.config-path }

Profile config evaluation with more granularity

> debug profile { source $nu.config-path } --max-depth 4


The profiler profiles every evaluated pipeline element inside a closure, stepping into all commands calls and other blocks/closures.

The output can be heavily customized. By default, the following columns are included:

  • depth : Depth of the pipeline element. Each entered block adds one level of depth. How many blocks deep to step into is controlled with the --max-depth option.
  • id : ID of the pipeline element
  • parent_id : ID of the parent element
  • source : Source code of the pipeline element. If the element has multiple lines, only the first line is used and ... is appended to the end. Full source code can be shown with the --expand-source flag.
  • duration_ms : How long it took to run the pipeline element in milliseconds.
  • (optional) span : Span of the element. Can be viewed via the view span command. Enabled with the --spans flag.
  • (optional) expr : The type of expression of the pipeline element. Enabled with the --expr flag.
  • (optional) output : The output value of the pipeline element. Enabled with the --values flag.

To illustrate the depth and IDs, consider debug profile { if true { echo 'spam' } }. There are three pipeline elements:

depth id parent_id 0 0 0 debug profile { do { if true { 'spam' } } } 1 1 0 if true { 'spam' } 2 2 1 'spam'

Each block entered increments depth by 1 and each block left decrements it by one. This way you can control the profiling granularity. Passing --max-depth=1 to the above would stop at if true { 'spam' }. The id is used to identify each element. The parent_id tells you that 'spam' was spawned from if true { 'spam' } which was spawned from the root debug profile { ... }.

Note: In some cases, the ordering of piepeline elements might not be intuitive. For example, [ a bb cc ] | each { $in | str length } involves some implicit collects and lazy evaluation confusing the id/parent_id hierarchy. The --expr flag is helpful for investigating these issues.