Skip to content

Local Docker: server-side realtime.send() broadcasts not delivered (missing replication slot) #1730

Description

@Sallvainian

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

  1. supabase start
  2. 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();
  3. Call realtime.send() from SQL (e.g., inside an RPC):
    PERFORM realtime.send(
      '{"key": "value"}'::jsonb,
      'my_event',
      'my-channel',
      true
    );
  4. Expected: Client receives the broadcast via WebSocket
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions