Quality of Service (QoS)
Choose the right delivery guarantee for your messages. NoLag supports three QoS levels for different reliability requirements.
QoS Levels
Quality of Service determines how NoLag handles message delivery. Different use cases require different guarantees:
| Level | Name | Guarantee | Use Case |
|---|---|---|---|
0 | At-most-once | Fire and forget | Telemetry, status updates |
1 | At-least-once | Acknowledged delivery | Notifications, chat messages |
2 | Exactly-once | Transactional | Payments, critical events |
QoS 0: At-most-once
Messages are sent once with no acknowledgment. The fastest option, but messages may be lost if the connection drops.
// Fire and forget - no delivery confirmation
client.emit('sensors/temperature', { temperature: 72.5 }, { qos: 0 })Best for:
- Sensor data that updates frequently
- Live location updates
- Typing indicators
- Mouse cursor positions
QoS 1: At-least-once
Messages are acknowledged by the broker. If no acknowledgment is received, the message is resent. Messages may be delivered more than once.
// Acknowledged delivery
client.emit('notifications', { type: 'alert', message: 'You have a new message' }, { qos: 1 })Best for:
- Chat messages
- Notifications
- Event broadcasts
- Most real-time applications
QoS 2: Exactly-once
Messages are delivered exactly once using a four-step handshake. The most reliable but slowest option.
// Exactly-once delivery
client.emit('orders/status', { orderId: '12345', status: 'completed', amount: 99.99 }, { qos: 2 })Best for:
- Financial transactions
- Order processing
- Critical state changes
- Inventory updates
Choosing the Right QoS
Decision Guide
- Can you tolerate lost messages? → Use QoS 0
- Need delivery confirmation? → Use QoS 1
- Can't tolerate duplicates? → Use QoS 2
- Not sure? → Start with QoS 1 (recommended default)
Handling Duplicates (QoS 1)
When using QoS 1, implement idempotency to handle potential duplicate messages:
const processedMessages = new Set()
client.on('orders/new', (data, meta) => {
// Use a unique identifier from your data
const messageId = data.orderId
// Skip if already processed
if (processedMessages.has(messageId)) {
return
}
// Process the message
processOrder(data)
// Mark as processed
processedMessages.add(messageId)
// Clean up old IDs periodically
if (processedMessages.size > 10000) {
const entries = Array.from(processedMessages)
entries.slice(0, 5000).forEach(id => processedMessages.delete(id))
}
})Default QoS
You can set a default QoS level for all messages:
import { NoLag } from '@nolag/js-sdk'
// Set default QoS for all messages
const client = NoLag('your_access_token', {
qos: 1 // Default QoS level
})
await client.connect()
// Override per-message
client.emit('topic', data, { qos: 2 })