Skip to main content

Offline Message Queueing & Delivery ๐Ÿ“ฌ

Never lose a message again! Vaultys Peer SDK automatically handles offline peers with intelligent message queueing and guaranteed delivery.

๐ŸŽฏ The Challenge of P2P Messagingโ€‹

In traditional P2P applications, if a peer is offline, messages are lost. This creates a poor user experience:

  • โŒ Users miss important messages
  • โŒ Manual retry logic is complex
  • โŒ No delivery guarantees
  • โŒ Poor reliability perception

โœจ Our Solution: Seamless Offline Handlingโ€‹

Vaultys Peer SDK solves this with automatic message queueing:

  • โœ… 100% message delivery - Messages queue when peers are offline
  • โœ… Seamless reconnection - Queued messages deliver automatically
  • โœ… No code changes - Works with existing sendMessage() calls
  • โœ… Persistent storage - Queues survive app restarts
  • โœ… Smart retry logic - Exponential backoff prevents overload

๐Ÿš€ Zero-Configuration Usageโ€‹

Message queueing works out of the box - no configuration needed!

import { setupVaultysPeerSDK } from '@vaultys/peer-sdk';

const peer = setupVaultysPeerSDK();
await peer.initialize('did:vaultys:alice');

// Just send messages normally - queueing is automatic!
await peer.sendMessage('did:vaultys:bob', 'Hello Bob!');
// If Bob is offline, message queues automatically
// When Bob comes online, message delivers seamlessly

๐Ÿ“š How It Worksโ€‹

Message Flow Diagramโ€‹

Queue Behaviorโ€‹

  1. Detection: SDK automatically detects if peer is offline
  2. Queueing: Messages are queued in order (FIFO)
  3. Storage: Queue persists to configured storage provider
  4. Monitoring: SDK monitors for peer reconnection
  5. Delivery: When peer reconnects, messages deliver in order
  6. Confirmation: Delivery is confirmed before removing from queue

๐ŸŽจ Configuration Optionsโ€‹

While queueing works by default, you can customize the behavior:

const peer = setupVaultysPeerSDK({
messageQueue: {
// Enable/disable queueing (default: true)
enabled: true,

// Maximum messages to queue per peer
maxQueueSize: 1000,

// Maximum time to keep messages (ms)
maxQueueTime: 7 * 24 * 60 * 60 * 1000, // 7 days

// Persist queue to storage (survives restarts)
persistQueue: true,

// Retry strategy
retryStrategy: 'exponential', // or 'linear', 'fixed'

// Initial retry delay (ms)
retryDelay: 1000,

// Maximum retry attempts
maxRetries: 10,

// Batch delivery size
batchSize: 50,

// Compress queued messages
compression: true
}
});

๐Ÿ’ก Common Patternsโ€‹

1. Send and Forgetโ€‹

The simplest pattern - just send messages without worrying about online status:

// No need to check if peer is online!
async function sendChatMessage(did: string, text: string) {
await peer.sendMessage(did, text);
// SDK handles everything else
}

2. Track Delivery Statusโ€‹

Monitor when messages are actually delivered:

// Send with tracking
const messageId = await peer.sendMessage(did, 'Important message');

// Track delivery
peer.on('message-delivered', (delivery) => {
if (delivery.messageId === messageId) {
console.log('โœ… Message delivered at:', delivery.timestamp);
updateUIDeliveryStatus(messageId, 'delivered');
}
});

// Track queueing
peer.on('message-queued', (event) => {
console.log('๐Ÿ“ฌ Message queued for offline peer:', event.to);
updateUIDeliveryStatus(event.messageId, 'pending');
});

3. Priority Messagesโ€‹

Send high-priority messages that deliver first:

// High priority message
await peer.sendMessage(did, 'URGENT: Server maintenance', 'text', null, {
priority: 'high',
skipQueue: false // Still queue if offline
});

// Normal priority (default)
await peer.sendMessage(did, 'Regular update');

4. Bulk Messagingโ€‹

Send to multiple peers efficiently:

// Send to multiple peers - each queues independently
const recipients = ['did:vaultys:alice', 'did:vaultys:bob', 'did:vaultys:charlie'];

const results = await Promise.all(
recipients.map(did =>
peer.sendMessage(did, 'Team announcement')
.then(id => ({ did, messageId: id, status: 'sent' }))
.catch(err => ({ did, error: err, status: 'failed' }))
)
);

// Some may be delivered immediately, others queued
console.log('Delivery results:', results);

5. Queue Managementโ€‹

Inspect and manage the message queue:

// Get queue status
const queueInfo = peer.getQueueInfo();
console.log(`Total queued messages: ${queueInfo.totalMessages}`);
console.log(`Peers with queued messages: ${queueInfo.peersWithMessages}`);

// Get queued messages for specific peer
const queuedMessages = peer.getQueuedMessages('did:vaultys:bob');
console.log(`${queuedMessages.length} messages queued for Bob`);

// Clear queue for specific peer (use with caution!)
await peer.clearQueue('did:vaultys:bob');

// Retry failed messages immediately
await peer.retryFailedMessages();

๐Ÿ”„ Retry Strategiesโ€‹

Exponential Backoff (Default)โ€‹

Delays double with each retry, preventing server overload:

// Retry delays: 1s, 2s, 4s, 8s, 16s, 32s...
const peer = setupVaultysPeerSDK({
messageQueue: {
retryStrategy: 'exponential',
retryDelay: 1000,
maxRetries: 10
}
});

Linear Backoffโ€‹

Delays increase linearly:

// Retry delays: 1s, 2s, 3s, 4s, 5s...
const peer = setupVaultysPeerSDK({
messageQueue: {
retryStrategy: 'linear',
retryDelay: 1000,
maxRetries: 10
}
});

Fixed Intervalโ€‹

Same delay between retries:

// Retry every 5 seconds
const peer = setupVaultysPeerSDK({
messageQueue: {
retryStrategy: 'fixed',
retryDelay: 5000,
maxRetries: 10
}
});

๐ŸŽฏ Advanced Featuresโ€‹

Message Deduplicationโ€‹

Prevents duplicate messages from being queued:

const peer = setupVaultysPeerSDK({
messageQueue: {
deduplication: true,
deduplicationWindow: 60000 // 1 minute window
}
});

// These will be deduplicated if sent within window
await peer.sendMessage(did, 'Hello');
await peer.sendMessage(did, 'Hello'); // Ignored if within window

Queue Persistenceโ€‹

Queues survive app restarts:

const peer = setupVaultysPeerSDK({
storageProvider: new IndexedDBProvider(), // or any persistent provider
messageQueue: {
persistQueue: true,
persistenceKey: 'vaultys-message-queue'
}
});

// On app restart, queued messages are restored and delivery continues

Batch Deliveryโ€‹

Deliver multiple queued messages efficiently:

const peer = setupVaultysPeerSDK({
messageQueue: {
batchSize: 50, // Deliver up to 50 messages at once
batchDelay: 100 // Wait 100ms between batches
}
});

Message Expirationโ€‹

Auto-remove old messages from queue:

const peer = setupVaultysPeerSDK({
messageQueue: {
maxQueueTime: 24 * 60 * 60 * 1000, // 24 hours
cleanupInterval: 60 * 60 * 1000 // Check every hour
}
});

peer.on('message-expired', (event) => {
console.log('Message expired:', event.messageId);
});

๐Ÿš€ Coming Soon: Relay Serverโ€‹

We're open-sourcing our production-grade signaling server that also acts as a message relay!

What's Comingโ€‹

// Deploy your own relay server
// docker run -p 9000:9000 vaultys/signaling-relay

const peer = setupVaultysPeerSDK({
relay: {
host: 'your-relay.com',
port: 9000
},

relay: {
enabled: true,
maxOfflineTime: '30d', // Store for 30 days
maxMessageSize: '100MB', // Support large files
encryptAtRest: true, // Server-side encryption
}
});

// Messages relay through server for extended offline periods
await peer.sendMessage(did, 'Delivered even after weeks offline!');

Relay Featuresโ€‹

  • ๐Ÿ“ฆ Extended Storage: Keep messages for days or weeks
  • ๐Ÿ” End-to-end Encryption: Server can't read messages
  • ๐Ÿ“Š Analytics: Message delivery metrics
  • ๐ŸŒ Global Distribution: Deploy relays worldwide
  • โšก High Performance: Handle millions of messages
  • ๐Ÿ”„ Automatic Failover: Multiple relay support

๐Ÿ“Š Monitoring & Metricsโ€‹

Track queue performance:

// Get queue metrics
const metrics = peer.getQueueMetrics();
console.log('Queue metrics:', {
totalQueued: metrics.totalQueued,
totalDelivered: metrics.totalDelivered,
totalFailed: metrics.totalFailed,
averageQueueTime: metrics.averageQueueTime,
deliveryRate: metrics.deliveryRate
});

// Monitor queue events
peer.on('queue-stats', (stats) => {
updateDashboard({
queueSize: stats.size,
oldestMessage: stats.oldestMessageAge,
deliveryRate: stats.deliveryRate
});
});

๐ŸŽฏ Best Practicesโ€‹

Do's โœ…โ€‹

  • Let the SDK handle queueing automatically
  • Monitor delivery events for UI updates
  • Set reasonable queue size limits
  • Use persistent storage for important messages
  • Implement message expiration for time-sensitive content

Don'ts โŒโ€‹

  • Don't implement manual retry logic
  • Don't check peer status before sending
  • Don't store unlimited messages
  • Don't disable queueing without good reason
  • Don't clear queues without user consent

๐Ÿ”ง Troubleshootingโ€‹

Common Issuesโ€‹

IssueSolution
Messages not queueingCheck messageQueue.enabled is true
Queue growing too largeReduce maxQueueSize or add expiration
Messages not deliveringCheck peer connection and retry settings
Duplicate messagesEnable deduplication
Lost messages on restartEnable persistQueue with persistent storage

Debug Modeโ€‹

const peer = setupVaultysPeerSDK({
debug: true,
messageQueue: {
debugQueue: true // Extra queue logging
}
});

// Monitor all queue operations
peer.on('queue-operation', (op) => {
console.log('Queue operation:', op);
});

๐ŸŽ‰ Conclusionโ€‹

With Vaultys Peer SDK's automatic message queueing, you can build reliable P2P applications that work seamlessly regardless of peer connectivity. Your users will never miss a message, and you'll never have to write complex retry logic again!


Next: Learn about Passkey Authentication for passwordless security