Archetype 14 — Realtime Fanout #
What this archetype is #
An event is created once and delivered to many connected recipients quickly.
Examples: chat delivery, live comments, realtime notifications.
We will use channel chat delivery as the running example.
Layer 1: Entities and Postgres table design #
MessageState
DeliveryState
RecentWindowView
create table channel_messages (
message_id uuid primary key,
channel_id bigint not null,
sender_id bigint not null,
body text not null,
created_at timestamptz not null default now()
);
create index channel_messages_channel_created_idx
on channel_messages (channel_id, created_at desc, message_id desc);
Postgres usually holds durable message truth, not the websocket session tier.
Layer 2: Write path mechanics #
Write message #
insert into channel_messages (
message_id, channel_id, sender_id, body
) values ($1, $2, $3, $4);
Then publish to session/fanout tier via:
- NOTIFY/LISTEN for small systems
- outbox + broker for larger systems
Read recent history #
select *
from channel_messages
where channel_id = $1
order by created_at desc, message_id desc
limit 50;
Layer 3: Fault tolerance #
- missed delivery
- duplicate replay
- out-of-order fanout
- reconnect replay gap
Layer 4: Scale #
Default hotspots:
- fanout explosion
- websocket fleet pressure
- egress bandwidth
- hot room/channel
Common mitigations:
- durable append log separated from delivery tier
- replay windows
- room partitioning and dedicated hot-room fanout workers