Network Backends

HORUS automatically selects the optimal communication backend based on topology — no configuration needed. Every topic is shared-memory backed; cross-machine replication is available separately via the opt-in net feature.

ℹ️Network Transport Is Opt-In

HORUS ships transparent LAN replication over UDP in the horus_net crate, but shared memory is the only transport until you turn it on — see Network Transport (LAN replication) below.

Automatic Backend Selection

When you call Topic::new("name"), HORUS automatically detects the optimal backend based on the number of publishers, subscribers, and whether the message type is POD:

use horus::prelude::*;

// Just create a topic — backend is auto-selected
let topic = Topic::<CmdVel>::new("motors.cmd_vel")?;
topic.send(CmdVel::new(1.0, 0.0));

No configuration needed. The backend upgrades and downgrades dynamically as participants join and leave.

Shared-Memory Backends

Every topic is shared-memory backed, so every backend is cross-process. There are five SHM backends; Topic::new() picks one of the four auto-selected ones from the publisher/subscriber topology and whether the message type is POD:

BackendLatencyDetection Criteria
FanoutShm~40nssubs > 1, non-POD (broadcast)
PodShm~50nssubs > 1, POD (broadcast)
MpscShm~65nspubs > 1, subs <= 1
SpmcShm~70nsnever auto-selected — see below
SpscShm~85nspubs <= 1, subs <= 1

SpmcShm exists as a backend but detection never chooses it: its consumers share one tail and compete for messages, so a fast consumer would starve the others — the wrong semantics for pub/sub broadcast. Multi-consumer topics get PodShm or FanoutShm instead, where each subscriber reads the stream independently and a fast consumer cannot starve a slow one. Independent is not the same as lossless: these rings are latest-wins, so a subscriber that falls a full lap behind skips the messages the publisher overwrote.

The backend is selected based on:

  • Topology: Number of publishers and subscribers
  • Data type: POD (fixed-size, memcpy-able) types get the dedicated zero-copy path; variable-size types are serialized with bincode, which costs more per message than the POD path

Dynamic Migration

HORUS dynamically migrates between backends as topology changes:

Single publisher + single subscriber
  → SpscShm, ~85ns

Second subscriber joins (non-POD payload)
  → FanoutShm, ~40ns

A second publisher joins as well
  → FanoutShm, ~40ns (no migration — non-POD broadcast already uses the fanout matrix)

The extra subscriber leaves — two publishers, one subscriber
  → MpscShm, ~65ns

All but one publisher and one subscriber disconnect
  → SpscShm, ~85ns

Migration is transparent — send() and recv() calls are unaffected.

Performance Characteristics

MetricShared Memory
Latency40-85ns backend transport; non-POD payloads add bincode serialization on top
ThroughputMillions msg/s
Zero-copyYes for POD types (via mmap); non-POD types are bincode-serialized
Cross-machineNot by shared memory itself — add the opt-in net feature / horus run --net for ~50μs LAN replication

Network Transport (LAN replication)

Cross-machine topics are replicated by the horus_net UDP replicator. It is opt-in — build the horus crate with --features net, or run horus run --net:

TransportLatencyUse Case
Shared Memory40-85nsSame-machine IPC
UDP LAN replication (net feature)~50μsMulti-robot, cross-machine topics

Topic::new() continues to auto-select the optimal SHM backend either way. With the net feature enabled, replication auto-starts on scheduler.run() and discovers peers by UDP multicast (default group 224.0.69.72, port 9100); topics you subscribe to but do not publish are imported by default (import = "auto"). Configure it with the [network] section of horus.toml or the HORUS_NET_* environment variables: opt out with .network(false), HORUS_NO_NETWORK=1, or [network] enabled = false; narrow the surface with [network] import / HORUS_NET_IMPORT and [network] deny_export.

Zenoh is not the transport. It is an optional bridge package (horus install horus-zenoh) for cases UDP multicast cannot reach — cross-subnet or WiFi links.

See Also

  • Topic - Shared memory architecture and Topic API
  • Core API - Topic creation and usage