Skip to content

Topic Freshness and Stale Data Contracts

Last updated: 2026-05-09

Why It Matters

ROS 2 delivery does not automatically mean the data is still valid. A reliable subscription can receive an old sample after a stall. A transient-local topic can serve a previous map or state to a late joiner. A best-effort sensor stream can drop the one frame that would have prevented a fusion blind spot. SLAM and sensor fusion need per-topic freshness contracts that define when data is too old to trust, how stale data is detected, and what downstream components do when freshness is violated.

Freshness Contract Fields

Each production topic should have a manifest entry:

FieldMeaning
topicFully qualified ROS topic name.
typeROS interface type and package version.
publisher_ownerNode/component responsible for the contract.
expected_rate_hzNominal publish rate or event semantics.
max_interarrival_msMaximum receive period before WARN/ERROR.
max_age_msMaximum now - Header.stamp before data is stale.
max_transport_msMaximum receive timestamp minus source timestamp where available.
qosReliability, durability, history, depth, deadline, lifespan, liveliness.
freshness_actionDrop, hold last with degraded flag, reset, safe stop, or block activation.
replay_ruleHow the topic behaves under /clock, seek, split, and snapshot.

Topic Class Defaults

Topic classFreshness postureTypical QoS posture
Raw LiDAR/camera/radarLatest usable sample only; old samples are dropped before fusion.Best effort or reliable by link quality, volatile, small depth, explicit age gate.
IMUHigh-rate stream; gaps and stamp regressions are faults.Best effort or reliable by hardware path, volatile, depth sized for preintegration.
GNSS/INSLower-rate absolute updates; stale updates can corrupt EKF.Reliable where bandwidth allows, volatile, covariance and age gate.
Localization pose/twistState estimate must be fresh before planning.Reliable, volatile, tight depth, deadline/liveliness monitoring.
/tf dynamicMust cover consumer query times, not merely latest wall time.Standard TF QoS plus transform-age diagnostics.
/tf_staticStatic until calibration artifact changes.Transient local, reliable, repeat on bag split.
Maps and calibrationVersioned state, not high-rate stream.Transient local/reliable with artifact version checks.
CommandsStale commands are unsafe.Reliable, volatile, lifespan/lease/sequence checks, watchdog timeout.
DiagnosticsLow-rate health with its own freshness budget.Reliable enough for operations, stale diagnostics treated as unknown.

QoS and Freshness

QoS policyFreshness effectContract guidance
DeadlineDetects missing expected publications.Use for periodic localization, control, and critical sensor health topics.
LifespanDrops samples after a validity duration.Use where supported for commands and freshness-critical state, but still implement application age gates.
LivelinessDetects publisher loss independent of message data.Pair with topic monitors for critical publishers.
ReliabilityReliable delivery can increase tail latency under loss.Use reliable only with bounded depth and age checks on high-rate data.
History/depthLarge depth increases stale-data risk.Derive depth from allowed queue delay and input rate.
DurabilityTransient local replays old state to late joiners.Restrict to static/config/map data and validate version/age on receipt.

Failure Modes

Failure modeSymptomControl
Old reliable sampleCallback fires after stall and fusion accepts stale data.Age gate at callback start and QoS depth bound.
Latched stale stateLate node receives previous route/map/calibration as current.Version checks, validity intervals, and explicit activation barriers.
Rate OK, age badros2 topic hz passes but header age grows.Monitor Topic Statistics message age and application age.
Deadline onlyDeadline detects no publish but not delayed old publish.Combine deadline with age and source-to-receive latency.
Stale diagnostics/diagnostics reports old OK after component stalled.Diagnostic freshness gate and liveliness checks.
Replay first-frame hazardBag starts after needed static/map state was published.Repeat transient-local topics and include warmup pre-roll.
Multiple publishersTopic alternates fresh and stale data from different owners.Single-writer ownership or publisher GID/source identity validation.

Runtime Telemetry

MetricPurpose
topic_received_hzDetect low frequency and bursts.
topic_age_msDetect stale physical/application data.
topic_transport_msDetect middleware/network delay.
topic_deadline_missed_totalDetect missed periodic contracts.
topic_liveliness_lost_totalDetect dead publisher or partition.
topic_stale_drop_totalProve stale samples are rejected.
topic_last_valid_stampSupport incident replay and operator dashboards.
topic_publisher_gidDetect duplicate writers and source switches.

Acceptance Checks

  • Every topic consumed by SLAM, localization, fusion, planning, control, or recorder trigger logic has a manifest freshness entry.
  • Synthetic old messages are dropped or marked degraded before fusion output.
  • Reliable high-rate topics cannot accumulate more data than the freshness budget allows.
  • Transient-local topics include artifact version and activation checks.
  • Topic monitors detect NotReceived, low rate, significantly low rate, and timeout conditions for critical topics.
  • Replay clips include warmup state and prove freshness gates behave the same under /clock.

Sources

Public research notes collected from public sources.