Sep 5, 2026 · ros2 · humble · jazzy · upgrade
Should You Upgrade From ROS 2 Humble to Jazzy Yet?
Upgrade to Jazzy when a package you need has moved or your robot must outlive Humble's support window; otherwise finish the thing you are building first.
Upgrade to Jazzy if your robot has to keep receiving fixes past Humble's end of life; stay on Humble if your deadline arrives first. Jazzy is the current long-term release, and the packages you depend on drift toward it whether you are ready or not. The verdict flips when your real problem is control-loop timing, which no distro upgrade touches and which is what HORUS addresses. The rest of this post is for teams running a working Humble robot who are deciding whether this quarter is the one to move.
You did not want to spend a week thinking about this. Somebody on the team got a new laptop, it came with a newer Ubuntu, and the robot would not build on it. Then a sensor arrived and the driver in its box only listed the newer distro, so you patched around it, and the patch is now a fork with your name on the commits. Somebody else read that support ends in a year and asked, reasonably, whether that is a problem, and nobody could answer without opening a calendar.
Meanwhile the robot works. It has worked for months. It drives, it picks things up, it does the demo. The thought of pulling the floor out from under something that works, for no benefit a customer would notice, is genuinely unappealing, and you suspect the week will turn into three. But the reasons to move keep accumulating quietly, one driver and one laptop at a time, and none of them are urgent enough on their own to schedule.
Should you upgrade to Jazzy now or wait?
Upgrade when something external forces it, and not because a newer version exists. The good triggers are concrete: a package you need has a release for the newer distro and not for yours, your customer asks who is patching the operating system, a new machine will not run the old Ubuntu, or you are starting a robot that has to still be supported several years from now. Each of those is a sentence you can say out loud in a planning meeting.
The bad trigger is a feeling that you are behind. Being behind is not a symptom. A robot that works, on a distro that is still receiving fixes, is in a fine position, and the upgrade will cost you a real chunk of a real sprint that could have gone into the thing your robot is supposed to do.
Timing matters more than teams admit. The worst moment is two weeks before an integration deadline, when every unfamiliar error looks like the one that sinks you. The best is the boring week after a release, when the robot is stable and nobody is watching.
What is a ROS 2 distro, and what does end of life actually mean?
A distro is a dated snapshot of ROS 2 pinned to one Ubuntu release, and end of life is the day new fixes stop being published. Humble is paired with Ubuntu 22.04 and Jazzy with Ubuntu 24.04, and that pairing is not decorative: the prebuilt packages you install are compiled against that operating system's libraries. Choosing a distro is therefore choosing a Linux version, a Python version, a compiler, and a simulator generation all at once.
Long-term releases land on a two-year cadence and are supported for several years afterwards. When that support ends, nothing switches off, and your robot boots the next morning exactly as it did. What stops is the arrival of other people's work: security fixes for ROS 2 packages, new releases from sensor vendors, and repairs for bugs found after the cutoff.
That is the real cost of sitting past end of life. You have not lost software; you have been promoted to maintainer of software you did not write, at the moment the community that could have helped moved to a version you are not running. If you are still choosing between the two for a new project, the starting-distro comparison is the narrower question.
What are your actual options besides upgrading?
There are six, and only two involve upgrading this quarter. You can stay on Humble and accept that you own the patching once the window closes. You can move to Jazzy now, while the robot is calm. You can skip ahead to a newer long-term release, paying the disruption once rather than twice. You can containerise, so the robot's Linux and the developers' laptops stop having to agree. You can split the fleet, doing new work on the newer distro while the shipped robot stays put. Or you can decide the distro was never your problem.
That last one deserves a sentence, because it is the one people reach for wrongly. If the upgrade came up because your control loop misses its deadline, ROS 2 versions are not the variable: the transport under either distro converts each message into a neutral format and rebuilds it on arrival. HORUS is the open-source example of a different arrangement, a real-time middleware where Rust, Python and C++ share the same shared-memory ring buffers, so messages between processes on one machine are not serialised. It is Apache-2.0, validated in simulation, and it is not a distro upgrade in disguise.
How do the paths compare side by side?
Read the last column first and cross out every row that describes you. What survives is usually one row, occasionally two.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| Stay on Humble | Teams shipping something this quarter on a stable robot | Your current build, and what your dependencies pin | The deadline is close and nothing is blocked | Your product must be supported for years after the window closes |
| Move to Jazzy now | Teams whose blocked dependency already has a newer release | Ubuntu upgrades, rosdep, and your third-party packages | The robot is calm and the calendar is open | You are mid-integration with a demo approaching |
| Skip to a newer long-term release | Teams starting a robot that has to outlive two support windows | Which of your drivers exist that far forward | The project is young enough to absorb it | Vendor packages for your sensors have not arrived yet |
| Track a non-long-term release | Researchers and contributors who want current features | Building from source, and living with churn | Being early is part of the work | Anyone else depends on your build being reproducible |
| Containerise and defer | Teams whose laptops and robot disagree about Linux | Container images, device access, and networking | You need to stop the bleeding without a migration | Your team has never debugged a container that cannot see a device |
| Split old and new | Teams with a shipped robot and a next one | How to keep two build environments honest | New work should not be held hostage by old hardware | You have one robot and two developers |
| HORUS | Builders whose complaint is loop timing rather than package versions | Rust, Python or C++, and how your processes are split | Several processes on one machine must agree quickly | You need mapping, navigation or a vendor driver today |
Almost none of that table is about which distro is better. It is about what else in your life is pinned.
What does a stalled distro upgrade actually look like?
A stalled upgrade looks like a robot that builds on two developers' laptops and nowhere else. It starts well. The core workspace compiles on the new pairing in an afternoon, everyone is pleased, and then the list appears: one vendor driver with no release for the newer distro, a Python library whose system version now conflicts with something else, a simulator world that loads with the geometry subtly rearranged, and a custom message package that builds cleanly and then disagrees with the recorded logs.
Each item is small, and each is assigned to whoever noticed it. None are the priority, because the old robot still works, so the branch stays open. Three months later, continuous integration still runs the old image, the demo robot still boots the old card, and the new workspace lives in the heads of two people.
That is the failure mode worth designing against: not a difficult upgrade, but an unfinished one. A half-migrated project costs more than either end state, because every bug now has two possible homes and nobody is sure which one they are debugging.
Are you a hobbyist, a research group, or a team shipping a product?
These three should make different calls, and the difference is who else has to run your code. If you are building alone, upgrade when the tutorials and packages you actually follow have moved, because your ecosystem is whatever the people writing those examples are using. Being on the same version as the answers you search for is worth more to a solo builder than any support window.
A research group is answering to collaborators, reviewers and the student who inherits the repository next year. Match whatever your lab and your co-authors run, and write the pairing down in the readme. A result nobody can rebuild is a result that quietly expires, and distro drift is a common cause.
A product team has a different clock entirely. Somebody outside the company will eventually ask who supplies security fixes for the software on a machine sold to a customer, and "the community, until last spring" is not a comfortable answer. For product teams the support window is not a technical detail, it is a commitment you are making on behalf of people who will still own the robot in several years.
What does the hardware you ship on decide?
The compute board decides more of this than your preferences do. On a general-purpose machine, an Ubuntu upgrade is ordinary work. On a vendor-pinned board, the operating system arrives as part of the vendor's own image, along with drivers for the accelerator, the camera interface and the power management, and you do not get to move to a newer Ubuntu just because ROS 2 did. Until the vendor ships an image built on the newer base, your options are containers or patience.
That single fact reorders the whole decision for a lot of teams. It is why containerising is on the options list at all: it lets the robot keep the Linux its hardware requires while your workspace targets a different pairing.
If the robot ships as a flashed image, the upgrade also stops being a software task. Every unit in the field needs a new image, which means a rollout plan, a way to recover a bricked machine, and someone driving to a customer site if it goes wrong. Plan the field update before the code, not after.
How much time do you have before Humble stops getting fixes?
Enough that you should not panic, and not enough to ignore it for another year. Humble's window closes in 2027, which is far away in project terms and very close in product terms, because a robot designed now will be in service after that date. The gap between those two readings is where teams get caught: the decision feels like it can wait, right up until it becomes the thing blocking a customer commitment.
The practical move is to convert an eventual emergency into a scheduled item. Put the upgrade on a roadmap with a name and an owner, sized honestly, in a quarter that does not already contain a launch. An upgrade you chose is a week. An upgrade forced on you by a sensor vendor two weeks before a trade show is a month, and a bad month.
If your product is sold to customers who keep machines for years, do the arithmetic openly. Either the software under your robot is supported for its service life, or you are budgeting to maintain it yourself, and that budget belongs in the plan rather than in a surprise.
How much packaging and build work can your team absorb?
A distro upgrade is mostly a build and packaging job, not an algorithm job, and that is the skill it demands. The work is reading compiler errors from libraries you did not write, resolving dependencies that want different versions of the same thing, understanding why a package installs on one machine and not another, and rebuilding a container image without breaking device access. Nothing in that list is about robotics.
So the honest question is who on your team does this cheerfully. Some teams have someone who finds it satisfying, and for them the upgrade is a contained piece of work. Other teams are three roboticists who have never wanted to learn the packaging system and who will each lose two days to the same error.
If you are the second kind of team, the answer is not to avoid the upgrade forever. It is to buy the containerised path first, which lets you stop the immediate pain without a migration, and then do the real move deliberately with someone assigned to it. Guessing at build errors under deadline pressure is how a week becomes a quarter.
What do you give up by moving to Jazzy?
You give up a working disk image and every third-party package that has not moved yet, and those are the two costs people underestimate. The image is not just software: it is the accumulated result of settings someone applied at three in the morning during a demo and never wrote down. Rebuilding it exposes exactly how much of your robot exists only as undocumented state.
You also give up a share of the answers. Most replies you find when you paste an error into a search box were written by people running the older, longer-established distro. That advantage decays as the newer release matures, but on the day you upgrade it is real, and you will be filing the issue rather than finding it already filed.
And you give up the ability to say "it worked yesterday". For a while every strange behaviour has an extra suspect, and separating a genuine regression from a new default takes time you did not schedule. Keep the old image bootable until the new one has survived a full week of real use.
When is ROS 2 the better choice?
ROS 2 is the better choice for nearly every team asking this question, and HORUS is not the answer to a distro upgrade. If your robot maps a building and navigates it, the stack that does that lives in ROS 2. If your sensors come with vendor drivers, those drivers are ROS 2 packages. If you teach, publish, or hand your work to someone who has to reproduce it, the shared vocabulary is the point. None of that changes because an upgrade is annoying.
It is worth saying plainly, because frustration with an upgrade is a common reason people start reading about alternatives. Leaving a framework is a larger version of the work you are trying to avoid, and there is no navigation stack at the end of it.
The narrow case where a different transport genuinely helps is specific: several processes on one machine, a loop that must act on a number before the next tick, and visible motion that suffers when it does not. If that is not the sentence you would write about your robot, upgrade and move on. If it is, what leaving actually costs is the honest accounting.
Is the upgrade only about getting newer package versions?
No, and here is why: the distro is a contract about the whole machine, not a version number on a library. Moving from Humble to Jazzy changes which Ubuntu you run, which Python interpreter your nodes use, which compiler enforces which warnings, which simulator generation your worlds must load in, and which set of vendor packages exists for your hardware. Any one of those can be the thing that decides your schedule, and none of them appear in a changelog you would skim.
The layer underneath moved too. Alongside the long-standing DDS default, an officially supported alternative transport became available, which widens your options when a network misbehaves rather than fixing anything on its own. If discovery over Wi-Fi has been a recurring complaint, what changed underneath ROS 2 is worth reading before blaming the distro.
There is also a business reading that engineers often miss. For anyone selling a machine, the important property of a supported distro is that somebody else publishes security fixes for the operating system and the packages on it. That is what the support window buys, and it is why the answer to "why upgrade" is sometimes a compliance question rather than a technical one.
Will the upgrade break all of your code?
Partly, but not the way you think: your node bodies mostly survive, and the breakage lands in everything around them. The algorithm inside a node reads a sensor, does some maths and publishes a result, and none of that depends on which distro you built against. Message definitions for standard types are largely stable across releases, so the shape of your data usually travels fine.
What breaks is the scaffolding. Build files that call a macro whose signature changed. Launch files using a form that has been deprecated for two releases. Parameter declarations that were tolerant and are now strict. A third-party library that pinned an old version of something the new Ubuntu ships differently. Tests that pass locally and fail in a container because the Python version moved under them.
And the largest breakage is not in any file. It is the shared understanding of how your robot starts up: which node comes first, which topic is assumed to exist, what somebody hardcoded during a demo. Upgrades expose that knowledge by breaking it, which is uncomfortable and, in the long run, genuinely useful.
How do you decide this without losing a month?
Timebox the decision to one afternoon and make it with evidence rather than opinion. Start by listing every third-party package your robot needs that you did not write: sensor drivers, arm libraries, perception packages, the simulator. For each, check whether a release exists for the newer distro. That list alone answers the question for most teams, in either direction, before you compile anything.
Then do one build. Pull a container for the newer pairing, build the workspace, and note what fails without fixing anything. Replay one recorded run through your perception pipeline and see whether the output looks like it did before.
If the afternoon ends with a clean build and a working replay, schedule the upgrade for next month while the robot is calm. If it ends with three vendor packages that do not exist yet, you have your answer. Either way you spent an afternoon rather than a quarter, and you have a list to show someone instead of a feeling.
Here is the whole decision in five lines.
- If you are shipping something within the quarter and nothing is blocked -> stay on Humble, because an upgrade under deadline pressure is a month, not a week.
- If a driver or library you need has no release for your distro -> move to Jazzy, because you are already maintaining the gap yourself.
- If you are starting a robot that customers will own for years -> move to the newest supported long-term release, because the support window is a promise you are making.
- If your compute board's vendor image pins your Ubuntu -> containerise first, because the hardware decides before you do.
- If the complaint that started this was a stuttering control loop -> neither upgrade path helps, because the cause is in how processes exchange messages.
The HORUS Fit Framework reduces the same comparison to five axes: ecosystem size, setup effort, team size fit, deployment target, and licence. Score each path on all five and pick the one that is not weak on the axis you cannot afford to lose, usually the deployment target.
If the timing question is the one you keep circling back to after the upgrade is done, put HORUS on your reading list rather than your roadmap: star it so it is in your list when you start building.