The Complete Production SOP: How to Deploy and Run Supabase Realtime PostgreSQL CDC Broadcasts & Presence in Autonomous AI Agents
Step-by-step SOP to install and run Supabase Realtime CDC, Broadcast, and Presence in Codex, Claude Code, and Cursor. Includes verified prompts and fixes.
Technical Overview & Architectural Context
Autonomous coding agents frequently stumble when implementing Supabase Realtime architectures. When instructed to establish Change Data Capture (CDC) subscriptions or client presence states, LLMs regularly hallucinate deprecated v1 syntax (e.g., `supabase.from('table').on(...)`), forget to enable PostgreSQL replication flags on target tables via migration scripts, and omit channel unmounting hooks. These omissions lead to runaway WebSocket connections, zombie client listeners, and exhausted connection pools in production PostgreSQL clusters. The `supabase-realtime-postgres-sync` skill enforces deterministic boundaries across all modern agent environments (Codex, Claude Code, Cursor, and Windsurf). By encapsulating channel lifecycle constraints, replication prerequisite enforcement, and strict cleanup patterns into a standardized SKILL.md definition, the agent guarantees idempotent subscription handling, granular schema-filtered CDC broadcasts, and accurate presence synchronization without manual engineering intervention.
Prerequisites & Environment Requirements
Verified Search Intents & Long-Tail Queries Solved
This operational tutorial is engineered to provide deterministic solutions for these developer search queries:
Step-by-Step Execution Playbook
Local Environment Setup & SKILL.md Mounting
Create the local skill manifest directory and inject verified procedural rules into the agent runtime directory.
Autonomous runtimes parse local project configuration or user-level agent directories to determine available skills. For global discovery, mount the skill file into the runtime's designated skills folder (`.agents/skills/` or `.claude/skills/`). The frontmatter triggers match natural queries like 'subscribe postgres_changes supabase' and auto-load the SOP into system context without manual prompt preambles.
mkdir -p .agents/skills/supabase-realtime-postgres-sync && curl -fsSL https://askills.dev/api/skills/supabase-realtime-postgres-sync/raw -o .agents/skills/supabase-realtime-postgres-sync/SKILL.md---
name: "supabase-realtime-postgres-sync"
description: "Stream live database changes and user presence states directly to web clients with Supabase."
metadata:
author: "Supabase"
version: "1.0.0"
runtime_compatibility:
- "codex"
- "claude-code"
- "cursor"
- "windsurf"
triggers:
- "subscribe postgres_changes supabase"
- "supabase presence tracking"
- "supabase realtime broadcast"
permissions:
fs_read: true
fs_write: "workspace"
shell_exec: false
net_access: false
---
# Supabase Realtime PostgreSQL CDC Broadcasts & Presence
Implements Supabase Realtime: subscribing to PostgreSQL table changes (postgres_changes), client-to-client broadcasts (broadcast), tracking online user presence (presence), and managing channel cleanup.
## Execution SOP & Rules
1. Ensure table replication is enabled: `ALTER PUBLICATION supabase_realtime ADD TABLE <table_name>;`
2. Create channel: `const channel = supabase.channel('<room_name>');`
3. Listen to DB changes: `channel.on('postgres_changes', { event: 'INSERT', schema: 'public', table: '<table_name>' }, handleNewMessage);`
4. Track presence: `channel.on('presence', { event: 'sync' }, () => { const state = channel.presenceState(); }).subscribe();`
5. Always unsubscribe on component unmount: `supabase.removeChannel(channel);`Keep the SKILL.md under 400 tokens; autonomous agents retain focused instructions better when auxiliary explanations are omitted in favor of strict imperatives.
In sandboxed container environments like Codex Desktop, ensure file permissions allow read access across the workspace root so the YAML frontmatter can be indexed.
Environment Secrets & Supabase Client Validation
Inject verified Supabase connection parameters safely into local environment files without exposing keys in conversation logs.
Realtime subscriptions require an authenticated client initialization with anonymous or JWT bearer tokens. Ensure variables are bound inside `.env.local` or `.env` and typed in runtime configuration wrappers. Never paste live keys directly into LLM chats.
cat << 'EOF' > .env.local
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
EOFimport { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
if (!supabaseUrl || !supabaseAnonKey) {
throw new Error('Missing Supabase Environment Variables in lib/supabaseClient.ts');
}
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
realtime: {
params: {
eventsPerSecond: 10,
},
},
});Configure `eventsPerSecond` throttle limits during client instantiation to protect the browser UI thread from rendering spikes during high-throughput database updates.
Never add `SUPABASE_SERVICE_ROLE_KEY` to client-side bundles; Realtime WebSocket subscriptions must operate strictly under RLS policies with user/anon tokens.
Intent Matching & Trigger Invocation
Trigger deterministic code generation for CDC listeners and presence tracking using skill keywords.
Provide the agent with a targeted instruction containing registered triggers like `subscribe postgres_changes supabase` and `supabase presence tracking`. The runtime matcher intercepts these keywords, loads the SOP, and generates an unmount-safe custom React hook or event listener that conforms to Supabase v2 Realtime standards.
import { useEffect, useState } from 'react';
import { supabase } from '@/lib/supabaseClient';
import { RealtimeChannel } from '@supabase/supabase-js';
export interface Message {
id: string;
room_id: string;
content: string;
created_at: string;
}
export function useRealtimeMessages(roomId: string) {
const [messages, setMessages] = useState<Message[]>([]);
useEffect(() => {
const channel: RealtimeChannel = supabase
.channel(`room:${roomId}`)
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'messages',
filter: `room_id=eq.${roomId}`,
},
(payload) => {
setMessages((prev) => [...prev, payload.new as Message]);
}
)
.subscribe((status) => {
if (status === 'SUBSCRIBED') {
console.log(`Connected to room:${roomId}`);
}
});
return () => {
supabase.removeChannel(channel);
};
}, [roomId]);
return { messages };
}Always supply the explicit `filter` argument in `postgres_changes` configs to offload change-filtering logic from client memory directly to the Supabase Realtime server.
Omitting `supabase.removeChannel(channel)` in cleanup routines causes multiple parallel WebSocket channels to accumulate on route transitions, quickly hitting plan limits.
Verification, Linting & Output Quality Gate
Execute automated self-healing checks and type audits before accepting agent deliverables.
Ensure that the agent checks generated code with TypeScript compiler and ESLint to verify that channels are unmounted cleanly, return types match Supabase generated database types, and that no unhandled promise rejections occur during `.subscribe()` or `.unsubscribe()` lifecycle events.
npx tsc --noEmit && npx eslint 'hooks/**/*.ts' 'lib/**/*.ts'Instruct the agent in your prompt to 'verify cleanup return statements exist in all useEffect blocks using removeChannel'.
Watch out for `channel.unsubscribe()` vs `supabase.removeChannel(channel)`. Supabase v2 recommends `supabase.removeChannel(channel)` to ensure clean garbage collection from the client registry.
Real-World Scenario: Realtime Collaborative Workspace Document Sync with User Presence
“Using supabase-realtime-postgres-sync, create a Next.js client hook `useDocumentPresence` that tracks active users viewing a document (presence) and streams incoming document changes using `subscribe postgres_changes supabase`. Ensure proper channel cleanup on unmount.”
Runtime Troubleshooting & Failure Modes
Root Cause: The PostgreSQL publication `supabase_realtime` does not have the specified table included in replication, or Row Level Security (RLS) policies block anonymous/authenticated read access.
-- Run in Supabase SQL Editor
ALTER PUBLICATION supabase_realtime ADD TABLE public.messages;
-- Ensure RLS allows select
CREATE POLICY "Allow select for authenticated users" ON public.messages FOR SELECT TO authenticated USING (true);Root Cause: The React component re-instantiates `supabase.channel()` on every state change because channel creation was not enclosed within a stable `useEffect` or dependencies array was omitted.
// Ensure channel subscription is wrapped with stable dependencies
useEffect(() => {
const channel = supabase.channel(`doc:${docId}`);
channel.on('postgres_changes', { event: '*', schema: 'public', table: 'documents', filter: `id=eq.${docId}` }, handleUpdate).subscribe();
return () => {
supabase.removeChannel(channel);
};
}, [docId]); // Only re-subscribe if docId changesFrequently Asked Questions (Supabase Realtime PostgreSQL CDC Broadcasts & Presence SOP)
Q:Can I use Supabase Realtime PostgreSQL CDC Broadcasts & Presence across Codex, Claude Code, and Cursor simultaneously?
Yes. The skill conforms to the universal SKILL.md specification. By placing it inside `.agents/skills/supabase-realtime-postgres-sync/` or linking it in `.cursorrules` / `.clauderc`, Codex Desktop, Claude Code CLI, Cursor, and Windsurf can read and enforce the identical SOP.
Q:How does Supabase Realtime PostgreSQL CDC Broadcasts & Presence prevent context window overflow during long agent sessions?
The skill provides ultra-focused procedural rules and precise syntax patterns for Supabase v2 Realtime. Instead of sending sprawling documentation pages into the prompt, the agent retrieves only the specific triggers and lifecycle rules needed to write correct subscriptions and cleanup routines.
Q:Does this skill require escalated root or container permissions?
No. The skill operates with a verified security score of 98/100 (`fs_read: true`, `fs_write: 'workspace'`, `shell_exec: false`, `net_access: false`). It operates entirely within local workspace boundaries without requesting host network access or root privileges.
Ready to equip your autonomous agent with Supabase Realtime PostgreSQL CDC Broadcasts & Presence?
Copy the complete audited SKILL.md specification or download the 1-click zip bundle directly from our verified registry.