{
  "id": 12646686,
  "title": "Nodejs Queue Publish for Offline Users: 12-Minute Live Poll Notifications",
  "url": "https://urgent.news/2026/10/07/nodejs-queue-publish-for-offline-users-12-minute-live-poll",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-07T14:53:10.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/thalion51/nodejs-queue-publish-for-offline-users-12-minute-live-poll-notifications-4nac"
  },
  "original_language": "en",
  "account": "When designing a Node.js system for delivering notifications to users who may become disconnected during the delivery process, the most reliable approach is to queue events before publishing them. This ensures that even if a user loses connectivity, they will still receive the notification once they reconnect. The live channel acts as an acceleration path, while the queue and durable record serve as the delivery contract.\n\nIn a session with numerous participants and a limited time frame, such as a 12-minute poll with up to 4,000 participants, the ordering of events becomes crucial. The key question is not whether the server can publish, but rather what evidence proves that each intended recipient can access the event after reconnecting.\n\nTo achieve this, the event must have a stable identifier, a mechanism for deduplication, a means to maintain a reconnect cursor or a durable inbox, and retry logic that does not delete the sole copy of the event. The design should guarantee failure boundaries, direct request publishing, a low-latency process, and the ability to crash without losing the event. It should also allow for replayable work, idempotency, retention, and an auditable offline recovery process.\n\nThe recommended approach is to use a per-recipient inbox, which provides strong evidence of delivery when a user reconnects. A shared session log can complement this, but it should not carry the entire delivery promise. When closing a poll, the request should validate the result, assign an event ID, create inbox entries for each recipient, and enqueue a fan-out job within a single transactional boundary.\n\nThe worker then publishes to connected clients and records the attempts. The choice of broker is replaceable, but ordering and idempotency are not. The close_poll function inserts the event into the database and inserts inbox entries for each recipient, then commits the transaction and enqueues a job for fan-out.\n\nThe fan_out function retrieves pending inbox rows for a given event ID, creates an envelope with the event ID, type, data, and a link to fetch details, and sends the envelope to the recipient if live connections are available. If not, it records an attempt. Marking delivery after transport acceptance is insufficient evidence of a human seeing the notification. Adding a client acknowledgement or a durable cursor is necessary for stronger evidence.\n\nWhen reconnecting, the client presents its last applied event ID or cursor, and the server returns pending inbox rows after that point before resuming the live stream. Each (recipient_id, event_id) tuple should be applied only once to avoid duplicates, gaps, and false delivery claims. The envelope should be small and stable, containing the poll ID, result version, event ID, and a link to fetch details.\n\nWebRTC provides real-time connection and data-channel behavior, but it does not replace durable application storage or an offline inbox. The system should inject failure points after the inbox transaction, after the queue lease, after transport acceptance, and during reconnect pagination. This ensures that repeated work does not cause repeated user-visible effects.\n\nRetention should be defined based on session policy and compliance requirements. For a 12-minute poll, one hour of retention may be sufficient, but this depends on the specific needs of the session. Expired rows should be a terminal state, with metrics distinguishing expiry from success. Observing intent and outcome separately is important, with metrics tracking events created, pending rows, attempts, accepted pushes, acknowledgements, duplicate suppressions, and expirations. Alerts should be triggered based on the oldest pending row and retry growth, not just websocket count.\n\nA direct publish approach from the poll-closing request is not suitable for poll results that must survive a user's disconnection. This design choice carries operational weight, with considerations for storage churn, queue leases, and replay potential. It is essential for notifications that need to survive a sleeping laptop, but it may not be the best fit for disposable typing hints or telemetry where loss is acceptable.\n\nIn summary, when building a Node.js system for delivering notifications to offline users, it is crucial to queue events before publishing, maintain a per-recipient inbox with idempotent fan-out, and ensure strong evidence of delivery through client acknowledgements or durable cursors. This approach provides a reliable, auditable, and explainable system that can handle disconnections and offer a better user experience.",
  "summary": "Nodejs Queue Publish for Offline Users: 12-Minute Live Poll Notifications Short answer: in a Nodejs-style service, queue the result before you publish it so offline users still get notified. The live channel is an acceleration path; the queue and durable record are the delivery contract. A B2B SaaS session may have 4,000 participants answering within 12 minutes, including browsers that disappear…",
  "key_points": [
    "Queue events before publishing to ensure delivery to offline users",
    "Use per-recipient inbox with idempotent fan-out for strong delivery evidence",
    "Implement client acknowledgements or durable cursors for proof of notification visibility"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}