Skip to content

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

@Sallvainian

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions