Gazebo Classic vs. Modern Gazebo (gz-sim): A Decision Guide for Robotics Teams
Gazebo Classic 11 is end-of-life. This guide compares Classic with modern Gazebo (gz-sim) across architecture, physics, ROS integration, and migration cost, then shows a concrete validation path.
15 Sept 2026, 10:13 UTC

Gazebo Classic 11 reached end-of-life in January 2025. It no longer receives bug fixes, security patches, or OS support updates. So the real question for a robotics team today is not "Classic or modern Gazebo?" but "what is the cost of migrating, and can we absorb it now or later?" This guide lays out the constraints, compares the supported options, and shows a concrete validation path before you commit.
The decision and its constraints
Three constraints usually determine the answer before any feature comparison matters:
- ROS version. ROS 1 Noetic pairs with Gazebo Classic through
gazebo_ros_pkgs. ROS 2 distributions pair with modern Gazebo throughros_gz. If your robot stack is ROS 2-only, Classic is effectively off the table. - Plugin investment. Custom model and world plugins written against the Classic
gazebo::C++ API do not compile against modern Gazebo. They must be rewritten asgz::sim::systems. - Existing assets. SDF world and model files are largely portable between the two, but
<plugin>elements referencing Classic plugin names will fail to load and need replacement systems.
Comparing the supported options
| Aspect | Gazebo Classic 11 | Modern Gazebo (gz-sim) |
|---|---|---|
| Maintenance status | End-of-life (Jan 2025) | Active, with LTS releases (e.g., Harmonic) |
| Architecture | Single-process, monolithic | Modular libraries: gz-physics, gz-transport, gz-rendering |
| Physics engines | ODE-centric, optional alternatives | Pluggable via gz-physics (DART default, Bullet, TPE) |
| ROS integration | gazebo_ros_pkgs (ROS 1 focus) | ros_gz bridge (ROS 2) |
| Default rendering | Ogre1 | Ogre2 |
| Headless/server operation | Supported but heavier | Designed for it; server/GUI separation |
| Model ecosystem | Large legacy library | Growing; many legacy models portable |
Trade-offs that actually bite
Plugin rewrite cost is the big one. Classic plugins hook into the simulator through inheritance from classes like ModelPlugin. Modern Gazebo uses an entity-component-system design: you write a System that implements hooks such as Configure and PreUpdate, operating on entities and components rather than direct model pointers. The logic usually ports, but the structure does not. Budget real engineering time if you have more than a handful of custom plugins.
ROS integration is not drop-in. Topic names and message mappings in ros_gz differ from gazebo_ros_pkgs. Launch files, bridge configurations, and any code subscribing to simulator topics will need updates.
Physics behavior changes. If your work is contact-heavy (manipulation, grasping), the move from ODE to DART as the default engine can change contact behavior. Modern Gazebo's pluggable physics is an advantage here — you can benchmark DART against Bullet on your scenario — but you must re-tune rather than assume parity.
Rendering differs on the same hardware. Ogre2 in modern Gazebo handles GPU resources differently than Ogre1. Camera-heavy simulations (multiple depth cameras, high-resolution GPU lidar) may perform better or worse; measure on your target hardware.
Staying on Classic has a cost too. Unmaintained dependencies and shrinking OS support mean Classic becomes harder to install on newer distributions over time. Deferring migration is borrowing against future effort.
A concrete validation path
Before committing, run one representative world through modern Gazebo and compare against your Classic baseline. The following commands run in a shell on a machine with modern Gazebo installed (no root required for running the simulator; installation itself typically needs sudo for package manager access):
# Confirm the installed release and version
gz sim --versions
# Launch a world headless (-r runs, -s server-only without GUI)
gz sim -r -s /path/to/your_world.sdf
# In a second terminal: list transport topics
gz topic -l
# Echo a sensor topic once to verify data flows
gz topic -e -t /world/your_world/model/your_robot/link/camera_link/sensor/camera/image -n 1Expected checks: gz sim --versions prints the installed release name; the world loads with no "failed to load plugin" errors in the console; gz topic -l lists the sensor and joint-state topics you expect; the echo command returns a message rather than timing out. Placeholders like your_world and topic paths must match your SDF's <world name="..."> and model names — topic paths are derived from them.
Risks are modest: running a simulation is read-only with respect to your system, but a malformed SDF or a missing plugin will produce load errors, which is exactly what you want to surface now. Then compare against Classic:
- Load the same world in Classic and in gz-sim on the same hardware.
- Compare real-time factor (displayed in both simulators) over a fixed run duration.
- Compare sensor publish rates (e.g., with
gz topic -hzversus Classic'sgz topic hz). - For contact-critical work, run a scripted interaction (a grasp, a collision) in both and compare joint forces or object trajectories qualitatively.
Limitations and how to verify
Release pairings change over time. Before finalizing, check the official Gazebo release roadmap to confirm the current LTS release and its supported ROS 2 distribution pairing — the combination matters because ros_gz versions are matched to specific Gazebo and ROS releases. Also note that SDF portability is high but not total: verify every model, joint, and sensor in your migrated world loads without missing-plugin errors, since that is where portability breaks in practice.
The bottom line: for new projects, target modern Gazebo. For existing Classic projects, the migration cost is dominated by custom plugins and ROS integration glue — measure both against a representative world before scheduling the work.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.