Gazebo 11 uses the Ignition Common Profiler to check and visualize the performance of the different threads, functions and methods.

Gazebo 9 uses an internal fork of Ignition Common's profiler.

How to run and see the profiler results for Gazebo?

To use the compiler, Gazebo must be compiled from source with the CMake flag -DENALE_PROFILER=1, for example:

cmake .. --cmake-args -DENABLE_PROFILER=1

For example, if you are using colcon to compile Gazebo:

colcon build --cmake-args -DENABLE_PROFILER=1

After compiling Gazebo, launch the world you want to profile. For example,


There's a convenient launcher script (Linux and macOS) for starting Remotery.

  • On Gazebo 11:

  • On Gazebo 9:


The script should open the profiler output in a browser.

Profile data for each process goes to a different port, which can be chosen on the top of the page:

  • gzserver to port 1500
  • gzclient to port 1501

You should see plots corresponding to different theads, for example:

  • gzserver
  • [Ode,Bullet,Symbody,Dart]Physics
  • SensorManager

The following image shows the sensor manager timeline. In this case we have 5 different sensors: gps, imu, magnetometer, altimeter and contact. You can see what is the duration of the sensor manager loop (50ms) and how long it takes to update all the sensors (around 0.177ms), the rest of the time the thead will be sleeping.

You can see the update time of each sensor, all the sensors have two subtasks: generate data and then publish this data (fill the data structure and publish it).

In the following two images you can see the evolution of the OdePhysics and gzserver loops.

How can I add the profiler to custom Gazebo plugins?

Using Gazebo 11, you can add profiler points to any Gazebo plugin. This is not possible on Gazebo 9.

If you want to add the profiler to your own Gazebo plugins you need to follow these steps:

  • Include the header

     #include <ignition/common/Profiler.hh>
  • Link against the profiler library

    target_link_libraries(<your plugin name>
  • Add profiler macros to the update method or other periodic methods:


Sensor classes

Classes that inherit from gazebo::sensors::Sensor already have the macros in the UpdateImpl method. This method is called periodically and it's in charge of generating the data and publishing it.


Classes that inherit from gazebo::*Plugin can connect to the periodic world update event with gazebo::event::Events::ConnectWorldUpdateBegin. See the WindPlugin for example, this will call the WindPlugin::OnUpdate method for every simulation iteration:

this->dataPtr->updateConnection = event::Events::ConnectWorldUpdateBegin(
        std::bind(&WindPlugin::OnUpdate, this));

That callback is a good place to put the macros above.