Bug Report
Describe the bug
Server-side broadcasts via realtime.send() (called from SQL functions/triggers/RPCs) silently fail in local Supabase Docker. Messages are inserted into realtime.messages but never delivered to WebSocket clients.
Client-side broadcasts via channel.send() work correctly.
Originally filed as supabase/cli#4914 — redirected here per maintainer feedback.
Environment
- Supabase CLI: 2.75.0
- Realtime image:
public.ecr.aws/supabase/realtime:v2.73.2
- Platform: macOS (Darwin 25.4.0)
- PostgreSQL
wal_level: logical
To Reproduce
supabase start
- Subscribe to a broadcast channel from a browser client:
const channel = supabase.channel('my-channel', {
config: { broadcast: { self: false }, private: true }
});
channel.on('broadcast', { event: 'my_event' }, (msg) => {
console.log('Received:', msg);
});
channel.subscribe();
- Call
realtime.send() from SQL (e.g., inside an RPC):
PERFORM realtime.send(
'{"key": "value"}'::jsonb,
'my_event',
'my-channel',
true
);
- Expected: Client receives the broadcast via WebSocket
- Actual: Message is inserted into
realtime.messages table but never delivered. No errors raised.
Root Cause Investigation
The local Docker setup has:
- ✅
supabase_realtime_messages_publication exists with correct partitioned tables
- ✅
wal_level = logical
- ✅
realtime.send() inserts into realtime.messages successfully (218+ rows accumulated)
- ❌
pg_replication_slots returns 0 rows — no consumer exists for the publication
The Realtime service (v2.73.2) doesn't create a replication slot to consume from supabase_realtime_messages_publication, so inserts into realtime.messages are never picked up and delivered to WebSocket subscribers.
Verification queries
-- Shows 0 rows — no replication slot exists
SELECT slot_name, plugin, active FROM pg_replication_slots;
-- Publication exists with correct tables
SELECT schemaname, tablename
FROM pg_publication_tables
WHERE pubname = 'supabase_realtime_messages_publication';
-- Messages are accumulating but never consumed
SELECT count(*) FROM realtime.messages;
Impact
- Any project using server-side
realtime.send() (from triggers, RPCs, background jobs) will silently fail in local development
- The function appears to succeed (no errors), making this extremely hard to debug
- Client-side
channel.send() works fine, masking the issue when some events use client-side and others use server-side delivery
Workaround
Use client-side channel.send() after RPC success instead of server-side realtime.send() within the RPC.
Bug Report
Describe the bug
Server-side broadcasts via
realtime.send()(called from SQL functions/triggers/RPCs) silently fail in local Supabase Docker. Messages are inserted intorealtime.messagesbut never delivered to WebSocket clients.Client-side broadcasts via
channel.send()work correctly.Originally filed as supabase/cli#4914 — redirected here per maintainer feedback.
Environment
public.ecr.aws/supabase/realtime:v2.73.2wal_level: logicalTo Reproduce
supabase startrealtime.send()from SQL (e.g., inside an RPC):realtime.messagestable but never delivered. No errors raised.Root Cause Investigation
The local Docker setup has:
supabase_realtime_messages_publicationexists with correct partitioned tableswal_level = logicalrealtime.send()inserts intorealtime.messagessuccessfully (218+ rows accumulated)pg_replication_slotsreturns 0 rows — no consumer exists for the publicationThe Realtime service (v2.73.2) doesn't create a replication slot to consume from
supabase_realtime_messages_publication, so inserts intorealtime.messagesare never picked up and delivered to WebSocket subscribers.Verification queries
Impact
realtime.send()(from triggers, RPCs, background jobs) will silently fail in local developmentchannel.send()works fine, masking the issue when some events use client-side and others use server-side deliveryWorkaround
Use client-side
channel.send()after RPC success instead of server-siderealtime.send()within the RPC.