Realtime
Stack can run Supabase Realtime for your namespace so you can subscribe to database changes over WebSockets.
This page continues the demo flow from the Database and REST guides.
Quick Start
Open a psql session as the default user, then connect to stack-demo:
kubectl -n stack-demo exec -it stack-demo-db-cluster-1 -- psql -d stack-demo
Create a table in your Stack database
-- Create a table called "todos" -- with a column to store tasks. create table todos ( id serial primary key, task text );
Allow anonymous access
-- Turn on security alter table "todos" enable row level security; -- Allow anonymous access create policy "Allow anonymous access" on todos for select to anon using (true); -- Grant table access for anon + service role grant usage on schema public to anon, authenticated, service_role; grant select on table public.todos to anon, authenticated; grant all on table public.todos to service_role;
Enable Postgres Replication
alter publication supabase_realtime add table todos;
Install the client
Realtime uses WebSockets. You can test it with the official Supabase JavaScript client.
npm install @supabase/supabase-js ws dotenv
Create the client
Create a .env from Stack secrets, then create realtime-listen.mjs:
stack secrets --manifest demo.stack.yaml > .env
cat > realtime-listen.mjs <<'EOF' import dotenv from "dotenv"; import { createClient } from "@supabase/supabase-js"; import WebSocket from "ws"; dotenv.config(); const jwt = process.env.ANON_JWT; if (!jwt) { console.error("Set ANON_JWT before running this script."); process.exit(1); } globalThis.WebSocket = WebSocket; const supabaseUrl = "http://localhost:30010"; const supabase = createClient(supabaseUrl, jwt); supabase .channel("schema-db-changes") .on( "postgres_changes", { event: "*", schema: "public", table: "todos" }, (payload) => console.log(payload) ) .subscribe((status, err) => { if (err) { console.error("Realtime error:", err); } else { console.log("Realtime status:", status); } }); EOF
Run it:
node realtime-listen.mjs
Insert dummy data
Back in psql, insert a row to trigger the change event:
insert into todos (task) values ('Change!');
You should see
Realtime status: SUBSCRIBED { schema: 'public', table: 'todos', commit_timestamp: '2026-01-11T13:01:28.182Z', eventType: 'INSERT', new: { id: 3, task: 'Change!' }, old: {}, errors: null }
Technical notes
- Realtime runs as a separate deployment in your namespace.
- It uses the shared
jwt-authsecret for API JWT validation. - The nginx gateway exposes it under
/realtime/v1.