apps/docs/content/troubleshooting/realtime-warn-sending-broadcast-message.mdx
If you broadcast from the database with realtime.send or realtime.send_binary, you may see this in your Postgres logs:
WARNING: WarnSendingBroadcastMessage: <reason>
It means the function could not insert the row into realtime.messages, so that message was not broadcast. This shows up in an edge case where the message would not have reached anyone anyway. This guide explains when that is the case and when the warning points to a real problem.
Realtime broadcasts database changes by streaming the realtime.messages table through a replication slot. That slot only starts once a client connects over WebSocket and the connection process begins streaming. The slot is temporary and does not replay history, so it only delivers messages inserted after a client connected.
So if you call realtime.send while nobody is connected, the message would not reach anyone even if the insert succeeded. No connection means no listener. Dropping it is the same outcome.
This is why the log line is a warning and not an error.
The most common cause is a missing daily partition on realtime.messages. The table is partitioned by day, and realtime.send or realtime.send_binary does not create partitions itself. If no partition exists for the current day, the insert fails with a message like no partition of relation "messages" found for row, and you get the WarnSendingBroadcastMessage warning.
Partitions are created on these occasions:
| Where | When it runs |
|---|---|
| A client connects over WebSocket | The first time a client joins a channel for the project, after database migrations run |
| The scheduled janitor | Periodically (roughly every 3~4 hours depending on env config), when it deletes old messages and recreates the partition window. It only covers projects that are currently connected, or that connected since its previous run |
Each of these creates a rolling window of partitions: yesterday, today, and the next three days.
These occasions depend on a client connecting: the connection creates the partitions, and it also makes the project visible to the janitor on its next run. Janitor coverage is not permanent, so a project that stops connecting successfully drops out of it.
<Admonition type="note" title="What's not included">A project that has never had a WebSocket client connect has no partition to insert into, so broadcasting from the database before that point produces the warning.
Calling realtime.send or realtime.send_binary, the broadcast REST endpoint, and subscribe or replication operations do not create partitions. The tenant health check endpoint does not create them either, so opening the Realtime section in the Supabase Dashboard has no effect on them.
Because both mechanisms require a client to connect, a project whose clients cannot connect never gets new partitions. The warning keeps firing, and it looks like partition maintenance stopped on its own.
The usual cause is authentication. When every connection attempt is rejected, no partition is created, and old ones are never cleaned up. The newest partition stays at the last day a client connected.
Work through these checks before treating the warning as a partition problem:
Once a client connects, the partitions are created and maintained again.
If you see this warning repeatedly while clients are connected and partitions exist, the insert is failing for another reason. The actual cause is in the <reason> part of the log line (the underlying SQLERRM). Check your Postgres logs for that text rather than assuming it is a missing partition. Common examples are a constraint violation or a permissions issue on realtime.messages.