HORUS/blog

Sep 5, 2026 · robotics-middleware · single-computer · beginner-robotics · ros-2

Do You Need Middleware If Everything Runs on One Computer?

Not while your robot is one program. Once one computer runs several programs that cannot wait for each other, middleware earns its place. Here is the test.

Yes, once one computer runs several programs that must not wait for each other; until then a single program beats ROS 2 or anything lighter. One computer removes the network, not the problem: two jobs still need to run at their own pace. The verdict flips the moment a slow job and a timed job share one loop, which is where HORUS or ROS 2 starts paying. The rest of this post is for someone whose robot lives on one board and who is unsure whether the framework everyone recommends applies to them.

Everything you have is on one machine. There is no fleet, no second computer, no radio link to a base station — just a board on the robot running your code, and the whole thing fits in a bag. So when people talk about publishers, subscribers, discovery and quality-of-service settings, it reads like advice meant for somebody with a warehouse.

But something is wrong anyway. The camera step takes its time and the wheels roll a little further than you wanted before the turn begins. You tried moving the slow part onto a thread and it improved, then a different sensor started reading late instead. You added a flag to skip work when things get busy, then another flag to stop the first flag misfiring. A friend offered to help and there was nothing to hand them, because the robot is one file and you were both going to edit it.

Then you ask online and someone says use ROS, and someone else says ROS is overkill for one computer, and a third person says just use threads. All three sound confident. None of them asked what your robot actually does, and you are left unsure whether you have a structural problem or simply a slow camera.

Do you need middleware if everything runs on one computer?

You need middleware when one computer is running several programs that must not wait for each other, and not before that. The number of computers was never the deciding fact — the deciding fact is how many things on the robot need to happen independently. A robot that reads a sensor, decides and drives motors in one steady loop needs no middleware on one computer or on ten. A robot where a camera thinks for a while, a control loop holds a rhythm, and a planner works out a route needs something carrying data between those three, and it needs that even though all three sit on the same board. What one computer does change is the price. With no network in the picture, discovery is simple, clocks already agree, and data can move between programs without being packed up for a journey it is not taking. So the honest answer is that one computer makes middleware cheaper rather than unnecessary — and the question you should be asking is about independence, not hardware.

What is middleware when there is no network involved?

Middleware with no network is a delivery system between programs on the same machine: one program hands over a piece of data, and every program that asked for that kind of data receives it, with neither side knowing the other exists. Nothing about that description mentions cables. The camera program publishes frames without knowing whether anything reads them; the motor program asks for steering commands without knowing what produces them. Beyond delivery, middleware usually brings three things worth having on a single board. A way to start and stop a set of programs together, so the robot comes up the same way every time instead of depending on which terminal you typed in first. Agreed message shapes, so two programs mean the same thing by a distance reading and nobody discovers a unit mismatch by watching the arm swing. And tools for watching messages while the robot runs, which turns why did it do that into something you can look at rather than guess about. What middleware actually does in a robot covers the idea more slowly.

What are your options for moving data between programs on one machine?

You have seven realistic options, and the first is the right answer more often than the internet admits. Write one program and move nothing between anything. Keep one program but push the slow job onto its own thread. Write your own pipe, local socket or shared file and carry the data yourself. Let two programs meet through a file or a small local database, which is fine for settings and poor for control. Use the toolkit that came with your kit or arm, which handles everything the vendor sold you and nothing else. Adopt ROS 2, which brings navigation, mapping, drivers, recording and a large community, along with workspaces, build tooling and vocabulary to learn first. Or use a middleware built for programs sharing one computer: HORUS is an open-source real-time robotics middleware for Rust, Python and C++ where the three languages share the same shared-memory ring buffers, so messages are not serialised between processes on one machine, which suits a Python program working beside a compiled control loop — while ROS 2 stays the better answer when borrowed packages are what you actually need. A general broker such as MQTT is the seventh, familiar from home automation and loose about timing.

OptionWho it is forWhat it assumes you knowWhen to pick itWhen not to
One program, no middlewareAnyone building a first robotYour language and a hardware libraryEvery step finishes before the next reading mattersOne slow job is making another job wait
A thread inside one programBuilders whose sensor stalls the loopThreads and shared data in your languageThe structure is fine but one step is slowA crash in one part must not stop the motors
Your own pipe or local socketTinkerers who enjoy the plumbingFraming, data formats, timingTwo programs, a fixed system, no growth plannedA third program needs the same data
A file or small local databaseBuilders sharing settings and statusYour language's file or database handlingThe data is slow and nothing waits on itA control loop depends on that data being fresh
The vendor kit's own toolkitOwners of a complete arm or roverOnly the vendor's guideThe kit does everything the project needsYou add hardware the vendor never sold
ROS 2Builders needing borrowed navigation or driversLinux, workspaces, message types, launch filesThe robot's value is packages other people wroteYou want a small stack you can hold in your head
HORUSSmall teams mixing Python with a Rust or C++ loopYour message shapes and how your loops are timedPrograms share one computer and a loop must keep timeYou need many borrowed packages or several machines

What does it look like when one program has outgrown itself?

It looks like the robot getting worse whenever you add something useful. You add logging and the turn comes late. You improve the vision and the arm develops a hesitation you can hear. You find yourself writing conditions that skip work when the loop is behind, and then conditions about those conditions. A second symptom is that failure spreads: a camera hiccup stops the wheels, a bad reading raises an error and the arm drops what it was holding, because everything lives in the same program and nothing survives alone. A third is that you cannot experiment. Trying a new idea for vision means stopping the wheels, so you try fewer ideas than you would like and the robot improves more slowly. A fourth is social — nobody can help you, because helping means editing the file you are editing. None of these is about elegance or line count. Plenty of good robots are one long file. The problem is always the same underneath: two things that need to happen independently are sharing one thread of execution.

What should you use if you are learning on your own?

Use one program, and keep using it until the robot itself objects. This is not beginner advice you graduate from — it is what experienced people do with an unfamiliar machine, because the first weeks are about discovering that your distance sensor lies near a glass door and your left motor is slightly stronger than your right. Every layer between you and the hardware makes those discoveries slower. So keep the loop in one file, and spend your effort on a habit instead of an architecture: read the sensor in one function, decide in another, drive the motors in a third, and never let the deciding function reach out and touch hardware directly. That costs nothing now and means the day you split the program up, you are moving functions rather than untangling them. When the split does come, choose based on what is missing. If you need somebody else's navigation, that is ROS 2. If you need your own programs to share data on one board while a loop keeps time, a local middleware is a smaller step than it looks.

What if the whole robot runs on one small board?

A small board makes the lighter answers better and the heavy ones expensive, because everything you install competes for the same modest processor and memory. On a board also running a control loop and perhaps a camera pipeline, whatever carries your data should be something you barely notice. A shared-memory approach fits especially well here, because data written by one program is read by another where it lies, without a second copy being made, and copies are what a small board can least afford. ROS 2 runs on modern single-board hardware and many people do run it there — but you feel it in start-up time, in memory, and in the quantity of machinery running that your robot never touches. There is also a hardware trap worth naming: if a microcontroller is doing your motor control, then part of your robot is already a separate computer talking over a wire, and no middleware on the main board changes that boundary. Whether your robot should have one computer or several is worth settling before you choose anything.

What should you do if the robot has to work in a few weeks?

Change nothing structural in the last few weeks before a deadline. Whatever is fragile in the robot today, a new layer of plumbing will not fix it in the time available, and it will add a category of failure you have never debugged: programs starting in the wrong order, a message going nowhere because two sides disagree about a name, a machine that behaves on your laptop and not on the robot. Spend the weeks on the demo instead. If the loop stutters when the camera reads, take the smallest step that helps — process fewer frames, move the read onto a thread, ask less of the vision — and write down in the repository that you did it, so nobody mistakes a patch for a design decision. Afterwards, with nothing at stake, is exactly the right moment to restructure, and it will go faster because you now know precisely which part could not wait. Middleware repays a robot that must keep working. It punishes a robot that must work on Thursday.

What if Python is the only language you know well?

Python alone will carry you further than most people expect, and the wall you eventually hit is about the shape of the program rather than the language. Reading sensors, making decisions and driving motors in Python is pleasant, and a great deal of real robot work happens exactly that way. What becomes awkward is holding a steady rhythm while also doing something heavy, because the heavy work and the rhythm are competing inside one program. The first fix is threads, and that buys real time. The second fix is putting the heavy part in its own process — and that is the moment you have arrived at middleware whether or not you call it that. Many robots settle there permanently: the thinking in Python where it is comfortable to change, the timed loop in a compiled language that keeps its promises, and something carrying data between the two. Choosing a layer where Python and a compiled language read the same data without translation makes that arrangement much less painful than it sounds.

What do people build first, and why does it stop working?

Almost everyone builds one loop, then patches it, and the patches are what stop working. The loop reads, decides, acts, repeats, and it is genuinely correct. Then the camera arrives and the loop is too slow, so a thread appears. Then two threads want the same variable and an occasional strange reading appears, so a lock appears. Then the lock is held while a slow thing happens and the rhythm suffers, so a queue appears. Then the queue fills during a busy moment and you must decide what to throw away, so a policy appears. Every one of those steps is reasonable in isolation, and together they are a small messaging system you now maintain by hand while also building a robot. The trouble is not that the pieces are wrong. It is that they were never designed, so nobody can say what the robot does when two of them interact under load. That is usually the point at which adopting something built for the job costs less than continuing.

What do you give up by adding middleware to a one-computer robot?

You give up directness, and it is a genuine loss worth counting. A single program can be read top to bottom; a set of programs cannot, and understanding the robot now means understanding what flows between them as well as what happens inside them. You give up the debugger you are used to, because stepping through one program while another keeps sending data is a different skill. You take on start-up order and the failure where everything is running but two parts never found each other, which is the most common bad afternoon in this whole category. You accept message definitions as a thing that must be kept in agreement, and a version skew that shows as nonsense rather than as an error. And you accept setup: something to install, something to configure, something new for a colleague to learn. Against all that sits one thing — parts of your robot can now run, fail and be restarted independently — and whether that trade is good depends entirely on whether you needed independence at all.

When is ROS 2 the better choice?

ROS 2 is the better choice when the packages are the project, and that is true on one computer just as much as on several. A robot that must map an unfamiliar building, plan a route through it and behave sensibly when somebody steps into the corridor should use ROS 2, because ROS 2 supplies all three and HORUS supplies none of them. The same goes for a robot built around a sensor whose only maintained driver is a ROS 2 package, for a university project where the marking depends on the tooling, and for a team that plans to hire people who should be productive within a fortnight. ROS 2 also wins the moment the robot stops being one computer, since spreading programs across machines is a problem ROS 2 has already solved and a local-memory approach has not. And if you want a robotics job, ROS 2 is the vocabulary employers use. Whether ROS 2 is overkill for a hobby robot is the other half of this question.

Is middleware just for robots with several computers?

No, and here is why. The problem middleware solves is independence between parts, and independence is needed on one machine for exactly the same reasons it is needed across a network. Two jobs with different rhythms still collide when they share a loop, whether that loop is on one board or split across a building. A part that must survive its neighbour crashing still needs to be a separate process, and processes on one machine still need something to carry data between them. What genuinely changes with one computer is the difficulty, not the need: there is no network to lose messages, no clocks to reconcile, no discovery across subnets, and data can move between programs without being packaged for a journey it never takes. That is why the single-machine case has its own tools. Treating middleware as a network technology is the misunderstanding that leads people either to skip it when they need it, or to reach for something built for fleets when their robot fits on a shelf.

Will adding middleware make your robot slower?

Partly, but not the way you think. Sending data between two programs is more work than passing a variable inside one, so on paper you have added a step. In practice, what people actually experience is a robot that behaves more steadily, because the slow job stops holding up the timed job, and steadiness is what you feel when you watch the arm stop before it hits the table. That is the trade in one sentence: a little more work per message, in exchange for work that no longer piles up behind other work. How much that step costs depends heavily on how the data moves. Middleware that packs each message into bytes, hands them to the operating system and unpacks them again does noticeably more than middleware that lets both programs read the same memory. On one computer you can avoid the packing entirely, which is the entire argument for local shared-memory designs. Why shared memory keeps coming up explains the mechanism without demanding a systems background.

How do you decide whether your one-computer robot needs middleware?

List every job your robot does, then write beside each one how long it can be made to wait before something visible goes wrong. That is the whole test, and it works better on paper than in an argument. Reading a distance sensor, processing a frame, holding a wheel speed, logging, listening for a command from your phone — each gets a line, and each gets an honest answer about waiting. If everything can wait for everything else, keep one program and enjoy it, because a framework would add learning and no capability. If one job cannot wait while another takes its time, you need separate programs, and the only remaining question is what carries data between them. Answer that by asking what you would otherwise have to write yourself. If the answer is navigation, mapping or a driver, take ROS 2. If the answer is nothing much, because the interesting code is already yours, then a local layer costs less to adopt and less to understand. Which messaging approach fits your robot covers that second choice in detail.

Decide by situation rather than by what sounds professional:

When two options stay close, weigh them on the five axes of the HORUS Fit Framework — ecosystem size, setup effort, team size fit, deployment target, and licence — and take the one that loses on the fewest. No scores and no numbers, just five honest questions about your situation rather than about the software. And when your robot does outgrow one program, star HORUS on GitHub so it is in your list when you start building.

Found this useful? Share it:Discuss on HNShare on X