Skip to content

Commit 3852c43

Browse files
edgurgeldijonmustersCoolAssPuppy
authored
feat: add broadcast replay blog post (supabase#41089)
* feat: add broadcast replay blog post * add video embed --------- Co-authored-by: Jon Meyers <[email protected]> Co-authored-by: Prashant Sridharan <[email protected]>
1 parent 48c9d3e commit 3852c43

File tree

4 files changed

+158
-0
lines changed

4 files changed

+158
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
---
2+
title: 'Realtime: Broadcast Replay'
3+
description: ''
4+
author: eduardo_gurgel
5+
image: 2025-12-05-realtime-broadcast-replay/og.png
6+
thumb: 2025-12-05-realtime-broadcast-replay/thumb.png
7+
categories:
8+
- product
9+
tags:
10+
- realtime
11+
date: '2025-12-05'
12+
toc_depth: 2
13+
---
14+
15+
Today we're releasing Broadcast Replay for Realtime - a powerful new feature that enables private channels to access messages that were sent earlier, ensuring your users never miss critical updates.
16+
17+
## The Challenge: Missing Important Messages in Real-time Applications
18+
19+
Building real-time applications comes with unique challenges. What happens when:
20+
21+
- A user's connection drops momentarily?
22+
- Someone joins a collaborative session mid-way?
23+
- A page reload occurs during an important update?
24+
- Network interruptions cause missed messages?
25+
26+
Previously, these scenarios meant lost context and degraded user experiences. Users would miss important messages sent while they were disconnected, and developers had to implement complex workarounds to maintain state consistency.
27+
28+
## Introducing Broadcast Replay
29+
30+
Broadcast Replay solves these challenges by allowing private channels to retrieve messages that were sent before a client connected or while they were disconnected. This feature integrates seamlessly with our existing [Broadcast from Database](/docs/guides/realtime/broadcast#broadcast-from-the-database) functionality, storing messages in the `realtime.messages` table for up to 3 days.
31+
32+
It leverages the messages already stored when using Broadcast from Database. When you enable replay on a private channel, Realtime queries the partitioned `realtime.messages` table to retrieve historical messages based on your configuration.
33+
34+
The replay configuration accepts two parameters:
35+
36+
- **`since`** (required): Unix timestamp in milliseconds specifying the earliest point from which messages should be retrieved;
37+
- **`limit`** (optional): Number of messages to return (1-25, useful for preventing information overload).
38+
39+
You can see Broadcast Replay in action at [https://multiplayer.dev](https://multiplayer.dev/), where the chat box demonstrates how users can access historical messages when joining or reconnecting to a conversation.
40+
41+
## Real-World Use Cases
42+
43+
### Chat Applications
44+
45+
Display the most recent messages when users enter a chat room, providing immediate context without complex state management:
46+
47+
```jsx
48+
const chatChannel = supabase.channel(`chat:${roomId}`, {
49+
config: {
50+
private: true,
51+
broadcast: {
52+
replay: {
53+
since: Date.now() - 300000, // Last 5 minutes
54+
limit: 25, // Show last 25 messages
55+
},
56+
},
57+
},
58+
})
59+
```
60+
61+
### Live Sports Updates
62+
63+
Ensure fans never miss crucial moments, even after connection issues:
64+
65+
```jsx
66+
const gameChannel = supabase.channel(`game:${matchId}:key-events`, {
67+
config: {
68+
private: true,
69+
broadcast: {
70+
replay: {
71+
since: matchStartTime, // Replay from match start
72+
limit: 20, // Show key events
73+
},
74+
},
75+
},
76+
})
77+
```
78+
79+
### Collaborative Editing
80+
81+
Highlight recent changes in documents when users return:
82+
83+
```jsx
84+
const docChannel = supabase.channel(`doc:${documentId}`, {
85+
config: {
86+
private: true,
87+
broadcast: {
88+
replay: {
89+
since: lastSeenTimestamp, // Changes since last visit
90+
limit: 15,
91+
},
92+
},
93+
},
94+
})
95+
```
96+
97+
## Working with Replayed Messages
98+
99+
The triggered events are now enriched with metadata to recognise replayed messages.
100+
101+
```jsx
102+
{
103+
"event": "message",
104+
"meta": {
105+
"id": "55f92208-37c8-4c7b-930d-756f14586e55",
106+
"replayed": true
107+
},
108+
"payload": {
109+
"content": "Hello world",
110+
"createdAt": "2025-11-12T15:41:22Z",
111+
"id": "3f0e4cdf-f886-4b2c-b132-1cedb5c55acc",
112+
"username": "supabasito"
113+
},
114+
"type": "broadcast"
115+
}
116+
```
117+
118+
One can use the `meta.replayed` field to handle historical and live messages differently:
119+
120+
```jsx
121+
// Broadcast callback receives meta field
122+
channel.on('broadcast', { event: 'chat_message' }, (payload) => {
123+
const chatMessage = payload.payload as ChatMessage
124+
// Render replayed messages with a different aspect
125+
chatMessage.replayed = payload?.meta?.replayed ?? false
126+
setMessages((current) => [...current, chatMessage])
127+
})
128+
```
129+
130+
## Availability
131+
132+
Broadcast Replay is available today in **Public Alpha**. This feature requires:
133+
134+
- Supabase JavaScript client version 2.74.0 or later
135+
- Messages sent via [Broadcast from Database](/docs/guides/realtime/broadcast#broadcast-from-the-database)
136+
- Private channels with appropriate RLS policies
137+
138+
We're actively seeking feedback to refine this feature. If you encounter any issues or have suggestions, please [submit a support ticket](https://supabase.help/).
139+
140+
Check out our [documentation](/docs/guides/realtime/broadcast#broadcast-replay) for detailed implementation guides and more examples.
141+
142+
<div className="video-container">
143+
<iframe
144+
className="w-full"
145+
src="https://www.youtube-nocookie.com/embed/scbQlEH3pRc"
146+
title="Introducing Realtime Broadcast Replay"
147+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share"
148+
allowfullscreen
149+
/>
150+
</div>

apps/www/lib/authors.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,5 +777,13 @@
777777
"position": "Engineering",
778778
"author_url": "https://twitter.com/the_ross_man",
779779
"author_image_url": "https://github.com/mattrossman.png"
780+
},
781+
{
782+
"author_id": "eduardo_gurgel",
783+
"author": "Eduardo Gurgel",
784+
"username": "edgurgel",
785+
"position": "Engineering",
786+
"author_url": "https://github.com/edgurgel",
787+
"author_image_url": "https://github.com/edgurgel.png"
780788
}
781789
]
55.7 KB
Loading
55.7 KB
Loading

0 commit comments

Comments
 (0)