---
title: "Profiler"
canonical_url: https://developer.repebble.com/pebbleos/docs/subsystems/profiler/
last_updated: 2026-11-02
sdk_version: 4.33.1
---
# Profiler

Source: https://developer.repebble.com/pebbleos/docs/subsystems/profiler/

`subsys/profiler/` measures where CPU time goes, in cycles. Its public API is `include/pbl/profiler/profiler.h`, enabled with `CONFIG_PROFILER`.

## Nodes

A node accumulates the cycles spent between its start and stop calls, and how many times it was stopped. Nodes are defined next to the code they measure and collected at link time in the `.pbl_profiler_nodes` linker section, sorted by name:

```
PBL\_PROFILER\_NODE\_DEFINE(compositor);void compositor\_render\_app(void) {PBL\_PROFILER\_NODE\_START(compositor);...PBL\_PROFILER\_NODE\_STOP(compositor);}
```

Another file reaches the node with `PBL_PROFILER_NODE_DECLARE()`. Without `CONFIG_PROFILER` the node macros compile to nothing, so instrumented code needs no conditionals.

Starting and stopping a node is a syscall: code running unprivileged, such as the application library inside an app, may time nodes too. Calls from unprivileged code with anything but a defined node are ignored.

## Runs

`pbl_profiler_reset()` clears the run and every node, `pbl_profiler_start()` and `pbl_profiler_stop()` time the run, and `pbl_profiler_print_stats()` stops it and logs each node that ran, most cycles first, with its share of the run.

From the shell, `profiler start` resets and starts a run, and `profiler stop` stops it and prints the stats.

Generated from PebbleOS [bdb74b4cd](https://github.com/coredevices/pebbleos/commit/bdb74b4cdf02abd82ad34fefc95dfc6d1fa6f12f). This page is maintained in the pebbleos repository: [docs/subsystems/profiler.md](https://github.com/coredevices/pebbleos/blob/bdb74b4cdf02abd82ad34fefc95dfc6d1fa6f12f/docs/subsystems/profiler.md).
