CloudSignal Docs
Use Cases

Offline Caching

Queue messages while clients are offline and deliver them automatically on reconnect using persistent sessions.

Mobile apps, IoT devices, and browser tabs frequently lose connectivity. CloudSignal's persistent sessions ensure that messages published while a client is offline are queued by the broker and delivered automatically when the client reconnects.

Architecture

When a client connects with clean_start=false and a session expiry interval, the broker creates a persistent session. If the client disconnects, the broker queues all messages matching the client's subscriptions. On reconnect, queued messages are delivered in order before any new messages.

Client connected:
  → Subscribed to sensors/#
  → Receiving messages normally

Client disconnects (network loss):
  → Broker keeps session alive
  → New messages on sensors/# are queued

Client reconnects:
  → Queued messages delivered immediately (in order)
  → Normal real-time delivery resumes

How It Works

  1. Client connects with clean_start: false and a session_expiry_interval
  2. Client subscribes to topics - these subscriptions are stored by the broker
  3. Client disconnects - the broker retains the session and its subscriptions
  4. Messages arrive on subscribed topics while the client is offline - the broker queues them
  5. Client reconnects with the same client ID and clean_start: false
  6. Broker delivers all queued messages, then resumes normal delivery

QoS 0 messages are NOT queued for offline clients. Use QoS 1 or QoS 2 for messages that must survive disconnection.

Configuration

Connect with Persistent Session

import { connect } from '@cloudsignal/mqtt-client'

const client = await connect({
  host: 'wss://connect.cloudsignal.app:18885/',
  username: 'mobile-device-001',
  password: 'your-token',
  clientId: 'device-001', // Must be consistent across reconnects
  clean: false,           // Persistent session (clean_start=false)
  sessionExpiryInterval: 3600 // Keep session for 1 hour after disconnect
})

// Subscribe with QoS 1 to ensure offline queuing
await client.subscribe('alerts/#', { qos: 1 })
await client.subscribe('updates/device-001', { qos: 1 })

Handle Queued Messages on Reconnect

client.on('connect', (connack) => {
  if (connack.sessionPresent) {
    // Session was restored - queued messages will arrive shortly
    console.log('Session restored, receiving queued messages...')
  } else {
    // New session - need to re-subscribe
    console.log('New session, subscribing...')
    client.subscribe('alerts/#', { qos: 1 })
    client.subscribe('updates/device-001', { qos: 1 })
  }
})

client.on('message', (topic, payload) => {
  const data = JSON.parse(payload.toString())
  // Process message - works the same for queued and live messages
  handleMessage(topic, data)
})

Session Expiry Guidelines

Choose a session expiry interval based on your use case:

Use CaseRecommended Expiry
Mobile app (brief disconnections)300 - 3600 seconds (5 min to 1 hour)
IoT device (intermittent connectivity)3600 - 86400 seconds (1 hour to 1 day)
Desktop app (overnight disconnection)86400 seconds (1 day)
Critical monitoring604800 seconds (1 week)

Longer expiry intervals mean more messages may be queued, consuming broker memory. Balance reliability against resource usage.

Message Queue Limits

CloudSignal enforces per-client queue limits based on your plan tier to prevent unbounded memory growth:

PlanMax Queued Messages
Free100
Pro10,000
Business100,000
EnterpriseCustom

When the queue limit is reached, the oldest messages are dropped to make room for new ones. Monitor your queue depths through the CloudSignal dashboard to right-size your plan.

Publishing with QoS for Offline Delivery

When publishing messages that offline clients should receive, use QoS 1 or higher:

// QoS 0 - NOT queued for offline clients
client.publish('updates/all', payload, { qos: 0 })

// QoS 1 - Queued and delivered at least once
client.publish('updates/all', payload, { qos: 1 })

// QoS 2 - Queued and delivered exactly once
client.publish('updates/all', payload, { qos: 2 })

The effective QoS is the minimum of the publish QoS and the subscription QoS. If you publish at QoS 1 but the client subscribed at QoS 0, the message is delivered at QoS 0 and will not be queued.

Next Steps

On this page