Quality of Service Overview
Quality of Service (QoS) policies control how DDS delivers data, providing fine-grained control over reliability, timing, resource usage, and more.
Why QoS?
Different applications have different requirements:
| Use Case | Requirements |
|---|---|
| Sensor streaming | High rate, some loss OK |
| Commands | Guaranteed delivery, ordered |
| State sync | Late joiners get current state |
| Real-time control | Low latency, deadline monitoring |
QoS policies let you configure these behaviors declaratively.
QoS Policy Categories
┌─────────────────────────────────────────────────────────────┐
│ QoS Policy Groups │
├─────────────────┬─────────────────┬─────────────────────────┤
│ Data Delivery │ Timing │ Resource Management │
│ - Reliability │ - Deadline │ - History │
│ - Durability │ - Latency Budget│ - ResourceLimits │
│ - History │ - Lifespan │ │
├─────────────────┼─────────────────┼─────────────────────────┤
│ Ownership │ Ordering │ Lifecycle │
│ - Ownership │ - DestinationOrd│ - Liveliness │
│ - OwnershipStr │ - Presentation │ - WriterDataLifecycle │
│ │ │ - ReaderDataLifecycle │
├─────────────────┴─────────────────┴─────────────────────────┤
│ Metadata: UserData, TopicData, GroupData, Partition │
└─────────────────────────────────────────────────────────────┘
Core QoS Policies
Reliability
Controls whether data delivery is guaranteed:
// Best effort - may lose samples (default)
let qos = DataWriterQos::default()
.reliability(Reliability::BestEffort);
// Reliable - guaranteed delivery with retransmits
let qos = DataWriterQos::default()
.reliability(Reliability::Reliable {
max_blocking_time: Duration::from_secs(1),
});
Durability
Controls data persistence for late-joining subscribers:
// Volatile - no history for late joiners (default)
let qos = DataWriterQos::default()
.durability(Durability::Volatile);
// Transient Local - keep samples in memory
let qos = DataWriterQos::default()
.durability(Durability::TransientLocal);
// Persistent - survive process restart
let qos = DataWriterQos::default()
.durability(Durability::Persistent);
History
Controls how many samples are kept:
// Keep last N samples per instance (default: 100)
let qos = DataWriterQos::default()
.history(History::KeepLast { depth: 10 });
// Keep all samples
let qos = DataWriterQos::default()
.history(History::KeepAll);
QoS Compatibility
Writers and readers must have compatible QoS to communicate:
Writer QoS Reader QoS Match?
──────────────────────────────────────────────────
Reliable --> Reliable Yes
Reliable --> BestEffort Yes
BestEffort --> BestEffort Yes
BestEffort --> Reliable NO
Persistent --> Persistent Yes
Persistent --> TransientLocal Yes
Persistent --> Volatile Yes
TransientLocal--> TransientLocal Yes
TransientLocal--> Volatile Yes
TransientLocal--> Persistent NO
Volatile --> Volatile Yes
Volatile --> TransientLocal NO
Rule: Writer must offer at least what Reader requests.
Applying QoS
At Creation Time
// Topic QoS (defaults for endpoints)
let topic_qos = TopicQos::default()
.reliability(Reliability::Reliable { max_blocking_time: Duration::from_secs(1) });
let topic = participant.create_topic_with_qos::<Data>("Topic", topic_qos)?;
// Writer QoS
let writer_qos = DataWriterQos::default()
.history(History::KeepLast { depth: 100 });
let writer = publisher.create_writer_with_qos(&topic, writer_qos)?;
// Reader QoS
let reader_qos = DataReaderQos::default()
.history(History::KeepLast { depth: 50 });
let reader = subscriber.create_reader_with_qos(&topic, reader_qos)?;
QoS Inheritance
TopicQos
│
├──> DataWriterQos (inherits, can override)
│
└──> DataReaderQos (inherits, can override)
PublisherQos
│
└──> DataWriterQos (partition, presentation)
SubscriberQos
│
└──> DataReaderQos (partition, presentation)
Common QoS Profiles
Sensor Streaming
let qos = DataWriterQos::default()
.reliability(Reliability::BestEffort)
.durability(Durability::Volatile)
.history(History::KeepLast { depth: 1 });
State Synchronization
let qos = DataWriterQos::default()
.reliability(Reliability::Reliable { max_blocking_time: Duration::from_secs(1) })
.durability(Durability::TransientLocal)
.history(History::KeepLast { depth: 1 });
Command Queue
let qos = DataWriterQos::default()
.reliability(Reliability::Reliable { max_blocking_time: Duration::from_secs(30) })
.durability(Durability::Volatile)
.history(History::KeepAll);
Event Log
let qos = DataWriterQos::default()
.reliability(Reliability::Reliable { max_blocking_time: Duration::from_secs(5) })
.durability(Durability::Persistent)
.history(History::KeepAll);
Timing Policies
Deadline
Monitor data freshness:
let qos = DataWriterQos::default()
.deadline(Deadline::new(Duration::from_millis(100)));
// Writer must publish within 100ms, or deadline missed callback fires
Liveliness
Detect writer failures:
let qos = DataWriterQos::default()
.liveliness(Liveliness::Automatic {
lease_duration: Duration::from_secs(10),
});
// Writer automatically asserts liveliness
// Reader notified if writer stops for 10s
Lifespan
Auto-expire old samples:
let qos = DataWriterQos::default()
.lifespan(Lifespan::new(Duration::from_secs(60)));
// Samples older than 60s are automatically discarded
Resource Management
Resource Limits
let qos = DataReaderQos::default()
.resource_limits(ResourceLimits {
max_samples: 10000, // Total samples
max_instances: 100, // Unique keys
max_samples_per_instance: 100, // Per key
});
Time-Based Filter
let qos = DataReaderQos::default()
.time_based_filter(TimeBasedFilter::new(Duration::from_millis(100)));
// Receive at most one sample per 100ms
Metadata Policies
User Data
// Attach metadata to participant
let config = DomainParticipantConfig::default()
.user_data(b"app=sensor;version=2.1".to_vec());
Partition
// Filter communication
let pub_qos = PublisherQos::default()
.partition(Partition::new(vec!["sensors", "zone_a"]));
let sub_qos = SubscriberQos::default()
.partition(Partition::new(vec!["sensors", "zone_*"]));
QoS Policy Summary
| Policy | Applies To | Purpose |
|---|---|---|
| Reliability | Topic, W, R | Delivery guarantee |
| Durability | Topic, W, R | Historical data |
| History | Topic, W, R | Sample buffer |
| Deadline | Topic, W, R | Update rate |
| Liveliness | Topic, W, R | Failure detection |
| Lifespan | Topic, W | Sample expiration |
| ResourceLimits | Topic, W, R | Memory bounds |
| Ownership | Topic, W, R | Exclusive writers |
| OwnershipStrength | W | Writer priority |
| DestinationOrder | Topic, R | Sample ordering |
| Presentation | Pub, Sub | Access scope |
| Partition | Pub, Sub | Topic filtering |
| TimeBasedFilter | R | Rate limiting |
| UserData | Participant | Metadata |
| TopicData | Topic | Metadata |
| GroupData | Pub, Sub | Metadata |
Troubleshooting QoS
No Match (QoS Incompatible)
Warning: Writer and Reader QoS incompatible
Check:
- Reliability: Writer ≥ Reader
- Durability: Writer ≥ Reader
- Deadline: Writer ≤ Reader
- Liveliness: Writer kind ≥ Reader kind
Missed Deadlines
Warning: Deadline missed
Solutions:
- Increase deadline period
- Reduce publish rate
- Check for network issues
Resource Exhaustion
Error: ResourceLimitExceeded
Solutions:
- Increase
max_samples - Use
KeepLastinstead ofKeepAll - Consume samples faster
Next Steps
- Reliability - Detailed reliability guide
- Durability - Historical data
- Deadline - Timing requirements
- QoS Cheatsheet - Quick reference