Large Data / Fragmentation

Back to overview

The pain

Robotics moves big payloads — camera frames, point clouds, maps, occupancy grids. UDP datagrams are ~64 kB max, so DDS must fragment large samples and reassemble them reliably. In practice this is a recurring failure surface (29 reports):

  • Messages above an internal threshold are silently dropped — the notorious ~262 kB ceiling in some Fast DDS configs — so a point cloud just never arrives, with no error.
  • On lossy links (WiFi), a single lost fragment stalls reassembly: the kernel IP-fragmentation buffer fills, and on some stacks the receiver stops accepting data for seconds (a vendor-agnostic, kernel-level failure).
  • Large messages spike latency and bandwidth unpredictably, and block unrelated callbacks while the big sample is in flight.

Most recent example

Fast-DDS#5686 — “FastDDS High Latency using Large Data” (2025-03-05). Enabling the large-data path produces high, inconsistent latency — the large-message transport behaves very differently from the small-message path, which is exactly the kind of surprise that makes “just send the image” unreliable.

Reference list (most recent)

Date Source Problem
2025-03-05 Fast-DDS#5686 High, inconsistent latency on the large-data path
2024-11-15 cyclonedds#2139 “Unusual performance” with large messages
2024-04-19 ros2#1544 Inconsistent bandwidth on image transmission
2024-04-14 Fast-DDS#4684 Send-buffer sizing breaks past net.core.wmem_max
2024-03-12 ROS Discourse Large data on lossy networks: reassembly stalls

How ZeroDDS solves it

No silent cap, selective retransmit, and a transport that doesn’t tank on a single lost fragment.

  • No silent drop. ZeroDDS’s reassembly cap is 16 MiB by default (configurable via ZERODDS_MAX_SAMPLE_BYTES). The old “samples over N bytes vanish” failure was a 1 MiB Phase-1 cap that we found and removed; 2 / 4 / 8 MB samples reassemble byte-perfect through the full DCPS stack.
  • Selective fragment retransmit. ZeroDDS implements DATA_FRAG / NACK_FRAG with a fragment assembler that has DoS caps. A lost fragment triggers a NACK_FRAG that re-requests only the missing fragments, not the whole sample — verified native RTPS 2.5 at 30 % packet loss. The reassembly buffer is the application’s, with explicit caps, so the kernel-IP-fragmentation stall does not apply.
  • WiFi-safe fragment size. Application-level fragmentation at a WiFi-safe MTU keeps each fragment inside a single link-layer frame, so the lossy-network reassembly cliff is avoided by construction.
  • Variable-size zero-copy for same-host. For the same-machine path, ZeroDDS has a length-prefixed shared-memory ring (see shared memory) — variable-size, so point clouds and images do not need a hand-dimensioned fixed pool.

Why it no longer has to be a pain

The large-data cluster is silent caps + all-or-nothing reassembly + a large-data path that behaves nothing like the small-data path. ZeroDDS removes the silent cap, retransmits at fragment granularity, and keeps fragmentation on one well-tested path — so “just send the 4 MB point cloud” is the default that works, including over lossy WiFi.

Reproduce it yourself

# 2/4/8 MB samples through the full DCPS stack, byte-perfect, multicast-free:
crates/ros2-rmw/interop/run_largedata.sh

# Same, over a real WiFi link (throughput ~10.8 MiB/s):
crates/ros2-rmw/interop/run_wifi_largedata.sh

Back to overview · Next: Cross-vendor interop

Large-Data / Fragmentierung

Zurück zur Übersicht

Der Schmerz

Robotik bewegt große Payloads — Kamera-Frames, Punktwolken, Karten, Occupancy-Grids. UDP-Datagramme sind ~64 kB max, also muss DDS große Samples fragmentieren und zuverlässig reassemblieren. In der Praxis ist das eine wiederkehrende Fehler-Oberfläche (29 Reports):

  • Nachrichten über einer internen Schwelle werden still gedroppt — die berüchtigte ~262-kB-Decke in manchen Fast-DDS-Configs — sodass eine Punktwolke einfach nie ankommt, ohne Fehler.
  • Auf verlustbehafteten Strecken (WiFi) stallt ein einziges verlorenes Fragment die Reassembly: der Kernel-IP-Fragmentierungs-Buffer füllt sich, und auf manchen Stacks hört der Empfänger sekundenlang auf, Daten anzunehmen (ein vendor-agnostischer, Kernel-Level-Fehler).
  • Große Nachrichten spiken Latenz und Bandbreite unvorhersehbar und blockieren unverwandte Callbacks, während das große Sample in flight ist.

Jüngstes Beispiel

Fast-DDS#5686 — „FastDDS High Latency using Large Data” (2025-03-05). Das Aktivieren des Large-Data-Pfads produziert hohe, inkonsistente Latenz — der Large-Message-Transport verhält sich sehr anders als der Small-Message-Pfad, was genau die Art Überraschung ist, die „schick einfach das Bild” unzuverlässig macht.

Referenzliste (jüngste zuerst)

Datum Quelle Problem
2025-03-05 Fast-DDS#5686 Hohe, inkonsistente Latenz auf dem Large-Data-Pfad
2024-11-15 cyclonedds#2139 „Unusual performance” mit großen Nachrichten
2024-04-19 ros2#1544 Inkonsistente Bandbreite bei Bild-Übertragung
2024-04-14 Fast-DDS#4684 Send-Buffer-Sizing bricht jenseits net.core.wmem_max
2024-03-12 ROS Discourse Large-Data auf verlustbehafteten Netzen: Reassembly stallt

Wie ZeroDDS es löst

Kein stiller Cap, selektiver Retransmit und ein Transport, der nicht bei einem einzigen verlorenen Fragment einbricht.

  • Kein stiller Drop. Der Reassembly-Cap von ZeroDDS ist 16 MiB by default (konfigurierbar via ZERODDS_MAX_SAMPLE_BYTES). Der alte „Samples über N Bytes verschwinden”-Fehler war ein 1-MiB-Phase-1-Cap, den wir gefunden und entfernt haben; 2- / 4- / 8-MB-Samples reassemblieren byte-genau durch den vollen DCPS-Stack.
  • Selektiver Fragment-Retransmit. ZeroDDS implementiert DATA_FRAG / NACK_FRAG mit einem Fragment-Assembler, der DoS-Caps hat. Ein verlorenes Fragment triggert ein NACK_FRAG, das nur die fehlenden Fragmente neu anfordert, nicht das ganze Sample — verifiziert byte-identisch bei 30 % Packet-Loss. Der Reassembly-Buffer gehört der Anwendung, mit expliziten Caps, sodass der Kernel-IP-Fragmentierungs-Stall nicht zutrifft.
  • WiFi-sichere Fragment-Größe. Application-Level-Fragmentierung an einer WiFi-sicheren MTU hält jedes Fragment innerhalb eines einzigen Link-Layer-Frames, sodass die Lossy-Network-Reassembly-Klippe by construction vermieden wird.
  • Variabel-große Zero-Copy für Same-Host. Für den Same-Machine-Pfad hat ZeroDDS einen längen-präfixierten Shared-Memory-Ring (siehe Shared Memory) — variabel-groß, sodass Punktwolken und Bilder keinen hand-dimensionierten Fixed-Pool brauchen.

Warum es kein Schmerz mehr sein muss

Der Large-Data-Cluster ist stille Caps + Alles-oder-nichts-Reassembly + ein Large-Data-Pfad, der sich gar nicht wie der Small-Data-Pfad verhält. ZeroDDS entfernt den stillen Cap, retransmittet auf Fragment-Granularität und hält Fragmentierung auf einem gut-getesteten Pfad — sodass „schick einfach die 4-MB-Punktwolke” der Default ist, der funktioniert, auch über verlustbehaftetes WiFi.

Selbst reproduzieren

# 2/4/8-MB-Samples durch den vollen DCPS-Stack, byte-genau, multicast-frei:
crates/ros2-rmw/interop/run_largedata.sh

# Dasselbe, über eine echte WiFi-Strecke (Durchsatz ~10,8 MiB/s):
crates/ros2-rmw/interop/run_wifi_largedata.sh

Zurück zur Übersicht · Weiter: Cross-Vendor-Interop