Offline Queuing
How Pipes.bot handles messages when your WebSocket client is disconnected.
When your WebSocket client is offline, Pipes.bot queues incoming messages and delivers them when you reconnect. No messages are lost during brief disconnections.
How queuing works
- A WhatsApp message arrives while no matching connection is open
- Pipes.bot stores the message in a Redis queue
- When you open a user-scoped connection, all queued messages are delivered automatically
- Messages are delivered oldest-first with a 750ms delay between each to avoid overwhelming your client
Queuing and connection scopes
Queuing behavior depends on which connections are active when a message arrives:
- At least one user-scoped connection open — message is delivered in real time, no queuing
- Only pool-number-scoped connections open — message is delivered to matching connections (by pool number); if no connection matches, the message is queued
- Only conversation-scoped connections open — message is delivered to matching connections; if no connection matches, the message is queued
- No connections open — message is queued
Queue drain only happens on user-scoped connections. Pool-number-scoped and conversation-scoped connections do not trigger a drain to avoid partial queue complexity. If you rely on scoped connections exclusively, use the REST API or a separate user-scoped connection to handle queued messages.
Queue limits
| Setting | Value |
|---|---|
| Max messages | 100 per sender per account |
| Queue TTL | 24 hours from the sender's most recent queued message |
| Overflow behavior | Oldest message dropped (FIFO) |
| Drain pacing | 750ms between messages |
The TTL is refreshed on every push, so a sender's queue expires 24 hours after their latest message — an active sender's older messages can survive well past 24 hours, and don't expire independently.
Per-sender queues
Queues are scoped per sender. If 5 different people message you while offline, each sender gets an independent 100-message queue. This prevents a chatty sender from pushing out messages from others.
Overflow
When a sender's queue reaches 100 messages, the oldest message is dropped to make room for the new one. This ensures you always receive the most recent messages.
Drain behavior
When you open a user-scoped connection:
- All queued messages across all senders are retrieved
- Messages are sorted by server enqueue time (
queuedAt), oldest first — not by the original WhatsApp message timestamp - Each message is delivered with a 750ms pause between sends
- The connection state is checked before each delivery — if you disconnect during drain, remaining messages stay queued
- Queues are cleared atomically to prevent duplicate deliveries
Webhook fallback
Warning: Webhook-to-WebSocket fallback is not wired up in V1. When webhook delivery fails all 3 attempts, the payload is persisted to the
WebhookDeliverytable with statuspendingfor manual retry — it is not delivered over WebSocket or re-queued. Do not rely on WS as an automatic webhook safety net.
- Webhook delivery is attempted up to 3 times (
0s / 2s / 8s, 10s timeout) - On exhaustion, the payload is saved to
WebhookDelivery(statuspending) - Reconcile persisted failures yourself (there is no automatic re-delivery)
Offline notifications
On the first message queued during an offline period, Pipes.bot sends a WhatsApp message (from the pool number to the number that activated it — the fromNumber of the oldest conversation on that pool number) letting you know messages are waiting. This is not an email. It is deduplicated via a Redis key (offline_notified:{userId}) with a 1-hour TTL, so you get at most one notification per hour per offline period.
Queue expiry warnings
A background job runs every 15 minutes and, for any queue whose TTL is under 1 hour, sends the sender a WhatsApp warning that their queued messages will expire in ~1 hour (deduplicated for 2 hours).
App-scoped connections
BYON ak_ connections drain app-scoped queues (queue:app:{appId}:*) on connect, the same way user-scoped connections drain user queues. See WebSocket authentication.