Skip to content

Examples/Realtime

Team chat (example)

A Slack-like chat with channels, presence and mobile push. WebSocket gateways hold client connections and receive channel events from a pub/sub bus; the API writes messages to Postgres, Redis tracks presence and APNs/FCM reaches offline members. Replace any part with how your own system works.

Scale: 300k daily users, 2k messages/s peak, 1.5M open sockets

123456789101112CLIENTClient appsEDGELoad balancerSERVICEWebSocketgatewaySERVICEChat APIDATABASEPostgresCACHERedis presenceLOG / STREAMEvent busWORKERPush workerEXTERNALAPNs and FCMOBJECT STOREAttachmentstorage

Select a component to see what it is responsible for and which state it owns.

  1. 1Client apps → Load balancer: Open WebSocket
  2. 2Load balancer → WebSocket gateway: Upgrade to socket
  3. 3Client apps → Chat API: Send message
  4. 4Chat API → Postgres: Insert message
  5. 5Chat API → Event bus: Publish channel event
  6. 6Event bus → WebSocket gateway: Deliver to subscribed nodes
  7. 7WebSocket gateway → Client apps: Push new messages
  8. 8WebSocket gateway → Redis presence: Refresh presence TTL
  9. 9Client apps → Chat API: Load history
  10. 10Event bus → Push worker: Events for offline members
  11. 11Push worker → APNs and FCM: Send push
  12. 12Client apps → Attachment storage: Upload attachment
  • Request / response
  • Asynchronous
  • Server push
  • Bulk data

Select a part to trace its flows.

  • Request / response
  • Asynchronous
  • Server push
  • Bulk data

Parts 10

Flows 12

  1. 1Client apps → Load balancerOpen WebSocketRequest / response
  2. 2Load balancer → WebSocket gatewayUpgrade to socketRequest / response
  3. 3Client apps → Chat APISend messageRequest / response
  4. 4Chat API → PostgresInsert messageRequest / response
  5. 5Chat API → Event busPublish channel eventAsynchronous
  6. 6Event bus → WebSocket gatewayDeliver to subscribed nodesAsynchronous
  7. 7WebSocket gateway → Client appsPush new messagesServer push
  8. 8WebSocket gateway → Redis presenceRefresh presence TTLRequest / response
  9. 9Client apps → Chat APILoad historyRequest / response
  10. 10Event bus → Push workerEvents for offline membersAsynchronous
  11. 11Push worker → APNs and FCMSend pushRequest / response
  12. 12Client apps → Attachment storageUpload attachmentBulk data

Invariants 3

  • Everyone sees a channel's messages in the same order

    Per-channel sequence from UPDATE channels SET last_seq = last_seq + 1 RETURNING in the insert transaction; clients sort by seq and fetch gaps.

    Kept by

  • A retried send never duplicates a message

    Client-generated message id with a unique constraint; a duplicate returns the stored message.

    Kept by

  • A user whose gateway died stops showing online within a minute

    Presence keys have a 60 s TTL refreshed by heartbeats; nothing deletes them on crash.

    Kept by