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
Select a component to see what it is responsible for and which state it owns.
- 1Client apps → Load balancer: Open WebSocket
- 2Load balancer → WebSocket gateway: Upgrade to socket
- 3Client apps → Chat API: Send message
- 4Chat API → Postgres: Insert message
- 5Chat API → Event bus: Publish channel event
- 6Event bus → WebSocket gateway: Deliver to subscribed nodes
- 7WebSocket gateway → Client apps: Push new messages
- 8WebSocket gateway → Redis presence: Refresh presence TTL
- 9Client apps → Chat API: Load history
- 10Event bus → Push worker: Events for offline members
- 11Push worker → APNs and FCM: Send push
- 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
- 1Client apps → Load balancerOpen WebSocketRequest / response
- 2Load balancer → WebSocket gatewayUpgrade to socketRequest / response
- 3Client apps → Chat APISend messageRequest / response
- 4Chat API → PostgresInsert messageRequest / response
- 5Chat API → Event busPublish channel eventAsynchronous
- 6Event bus → WebSocket gatewayDeliver to subscribed nodesAsynchronous
- 7WebSocket gateway → Client appsPush new messagesServer push
- 8WebSocket gateway → Redis presenceRefresh presence TTLRequest / response
- 9Client apps → Chat APILoad historyRequest / response
- 10Event bus → Push workerEvents for offline membersAsynchronous
- 11Push worker → APNs and FCMSend pushRequest / response
- 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