Performance Monitoring.

The perfmon module lets you instrument your code and visualize its run-time behavior and timings in Chrome’s Tracing GUI.

To enable perfmon define the env var NAPARI_PERFMON as follows:


Activates perfmon, trace using Debug -> Performance Trace menu.


Configure perfmon using the config.json configuration. See the PerfmonConfig docs for the spec of the config file.

Chrome Tracing#

Chrome has a nice built-in performance tool called chrome://tracing. Chrome can record traces of web applications. But the format is well-documented and anyone can create the files and use the nice GUI. And other programs accept the format including: 1) which does flamegraphs (Chrome doesn’t). 2) Qt Creator’s performance tools.

Monkey Patching#

The best way to add perf_timers is using the perfmon config file. You can list which methods or functions you want to time, and a perf_timer will be monkey-patched into each callable on startup. The monkey patching is done only if perfmon is enabled.

Trace On Start#

Add a line to the config file like:

“trace_file_on_start”: “/Path/to/my/trace.json”

Perfmon will start tracing on startup. You must quit napari with the Quit command for napari to write trace file. See PerfmonConfig docs.

Manual Timing#

You can also manually add “perf_timer” context objects and “add_counter_event()” and “add_instant_event()” functions to your code. All three of these should be removed before merging the PR into main. While they have almost zero overhead when perfmon is disabled, it’s still better not to leave them in the code. Think of them as similar to debug prints.



A performance related event: timer, counter, etc.


napari.utils.perf.add_counter_event(name: str, **kwargs: Dict[str, float]) None[source]#
napari.utils.perf.add_instant_event(name: str, **kwargs) None[source]#
napari.utils.perf.block_timer(name: str, category: str | None = None, print_time: bool = False, **kwargs)[source]#

Time a block of code.

block_timer can be used when perfmon is disabled. Use perf_timer instead if you want your timer to do nothing when perfmon is disabled.


Most of the time you should use the perfmon config file to monkey-patch perf_timer’s into methods and functions. Then you do not need to use block_timer or perf_timer context objects explicitly at all.

  • name (str) – The name of this timer.

  • category (str) – Comma separated categories such has “render,update”.

  • print_time (bool) – Print the duration of the timer when it finishes.

  • **kwargs (dict) – Additional keyword arguments for the “args” field of the event.


with block_timer("draw") as event:
print(f"The timer took {event.duration_ms} milliseconds.")
napari.utils.perf.perf_timer(name: str, category: str | None = None, **kwargs)[source]#