Supabase Realtime not working: find the missing update
If a row saves but the screen stays stale, separate the write, event delivery and UI update. Check that the table is in the supabase_realtime publication, the subscribing user can read the row, and the listener targets the correct schema, table and event. SUBSCRIBED alone does not prove that the intended change reached your app.
Why this matters
Reviewed against official documentation on 18 October 2026. This guide covers Postgres Changes, not Broadcast or Presence. The diagnostic example is illustrative, not a recorded test of your project. Use an owned disposable environment and non-sensitive records; do not turn off RLS to make events appear.
Find the first failed step
- Confirm the write succeeded and the intended row exists. If Save failed, diagnose that request before changing Realtime.
- Check the project URL used by the running client against the database you are editing. Confirm the expected table belongs to the supabase_realtime publication.
- Read the test row through the same signed-in client that subscribes. An administrator SQL query does not establish this user's access.
- Match schema, table, event type and filters. Observe the subscription status and the event callback separately.
- If the callback fires, inspect state updates and cache invalidation. If it does not, investigate subscription errors and provider logs before changing rendering code.
A note saves, but the second screen stays stale
Suppose user A creates a private note and another screen signed in as A does not update. Refreshing reveals it. Record the project, revision, user and row identifier. That observation separates a successful write from a failed live update; it does not yet locate the cause.
Inspect publication and same-user access
Run this read-only query in the intended project's SQL editor and check for your table. If it is missing, review the intended publication configuration before changing it.
For INSERT and UPDATE diagnostics, test SELECT access through the subscriber's session. Preserve the intended row policy. DELETE has separate filtering and authorization limitations; do not assume this test establishes its behavior.
select schemaname, tablename
from pg_publication_tables
where pubname = 'supabase_realtime';
Observe a narrow listener
Adapt this probe to an existing test table using your initialized Supabase browser client. It logs event metadata rather than row contents. Subscribe first, then perform a separate manual test insert. A write immediately after SUBSCRIBED can race listener setup; one missing initial event is not enough to diagnose an access problem.
Keep the probe active while testing. Call disposeProbe only on teardown. This is a diagnostic example, not a complete production React component.
const probe = supabase
.channel('diagnose-notes-insert')
.on('postgres_changes', {
event: 'INSERT',
schema: 'public',
table: 'notes',
}, (event) => {
console.info('Database event', {
type: event.eventType,
table: event.table,
});
})
.subscribe((status) => {
console.info('Realtime status', status);
});
async function disposeProbe() {
await supabase.removeChannel(probe);
}
Record delivery and rendering independently
Fill the observed column from your own run. These are expected outcomes, not completed checks. Test the real filtered listener after the narrow probe.
| Check | Expected | Observed |
|---|---|---|
| Save request | Row exists in the intended project | NOT TESTED |
| Same-user read | User A can read note A | NOT TESTED |
| Matching event | Listener receives the test INSERT | NOT TESTED |
| UI update | Note appears once without refresh | NOT TESTED |
| Different user | User B cannot read private note A | NOT TESTED |
Check cleanup and recovery
When a component unmounts or changes the record it watches, remove the old channel. Otherwise stale or duplicate subscriptions can make the UI misleading. Supabase exposes removeChannel for this cleanup.
Repeat navigation away and back, logout/login and reconnect. Re-fetch authoritative data after reconnect rather than assuming every missed event will be replayed. Record failures separately from successful checks.
Trace the code path in your app
Connect your repo and computer in VibeRaven, then ask your connected coding agent to trace the write handler, subscription, cleanup and UI update. Review the diff and project checks before rerunning the worksheet.
Repository evidence cannot establish your live publication, permissions or event delivery. Verify those in the intended Supabase environment.
Related guides
Sources
Why does SUBSCRIBED appear with no events?
A joined channel does not prove row delivery. Check publication membership, the subscriber's read access, selectors and timing. Record the callback and the visible UI separately.
Should I disable RLS to fix Realtime?
Keep the intended access rules. Test the same user's read and repair the specific policy or grant if it is wrong. A broad access change can expose data while hiding the original cause.
The callback runs, but React does not update. What next?
Inspect the state or cache update and confirm it applies to the currently visible record. Check for old listeners after navigation. Receiving an event and rendering it are different checks.