Supabase Realtime Ingestion & Channel Subscriptions
pg-channel database events to reactive client propagation
Published: 2026-06-20 | Project: Glassmetric | Discipline: Distributed Systems & High-Throughput State
Author: Nicholas Alexander MacAskill — Founder & CTO, Flocano Labs | Canonical: https://www.nicholasmacaskill.com/dossier/supabase-realtime-engine
Reactive Persistence Architecture
To ensure the dashboard operates as a live command center, the client does not rely on polling. Instead, it subscribes to PostgreSQL changes via Supabase's Realtime websockets. Biometric updates synced from the mobile background agent populate immediately on the dashboard HUD.
Database Schema and Indices
The PostgreSQL schema segregates raw updates into a metrics table with domain categorizations constrained by database enums, utilizing indexes optimized for time-series updates:
CREATE TYPE metric_domain AS ENUM ('health', 'trading', 'betting', 'social');
CREATE TABLE IF NOT EXISTS metrics (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
created_at TIMESTAMPTZ DEFAULT now(),
domain metric_domain NOT NULL,
name TEXT NOT NULL,
value FLOAT8 NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb
);
-- Indexes for high-frequency queries
CREATE INDEX IF NOT EXISTS idx_metrics_created_at ON metrics (created_at DESC);
CREATE INDEX IF NOT EXISTS idx_metrics_domain_name ON metrics (domain, name);Client-Side Pub/Sub Subscription
The Next.js web application registers client-side websocket channels inside Home() hooks. Whenever the background mobile worker inserts new records, the browser React tree re-renders reactively:
useEffect(() => {
if (!HAS_SUPABASE) return;
// Real-time metrics channel subscription
const metricsSub = supabase
.channel('metrics_updates')
.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'metrics' }, (payload) => {
const m = payload.new;
if (m.domain === 'health') setHealthMetrics(prev => ({ ...prev, [m.name]: m.value }));
if (m.domain === 'trading') setTradingMetrics(prev => ({ ...prev, [m.name]: m.value }));
if (m.domain === 'betting') setBettingMetrics(prev => ({ ...prev, [m.name]: m.value }));
if (m.domain === 'social') setSocialMetrics(prev => ({ ...prev, [m.name]: m.value }));
})
.subscribe();
return () => {
supabase.removeChannel(metricsSub);
};
}, []);