LIVE2025

Multi-tenant SaaS analytics platform

Orbit Analytics

Orbit started as a personal need — every analytics tool was either too expensive, too bloated, or required sending data to a third party. The goal was to build a self-contained, privacy-first analytics engine that a single developer could own and operate. The core challenge was query performance. At scale, aggregating millions of events across arbitrary date ranges and custom dimensions needs careful schema design. I landed on a denormalised event table with a materialised summary layer refreshed on a 5-minute schedule — giving the dashboard sub-100ms response times even for 30-day aggregations across 50k+ daily events.

Orbit Analytics dashboard screenshot

50k+

Daily Events

avg processed / day

<100ms

Query P95

across 30-day windows

Multi-tenant

Workspaces

full RLS isolation

The Core Challenge

Raw event tables don't query well at scale. A naive COUNT(*) GROUP BY across 30 days of dense event data hits timeout territory quickly. The solution was a two-layer architecture: a write-optimised raw events table using Postgres partitioning by day, plus a materialised summary table refreshed every 5 minutes via a scheduled Supabase Edge Function. The dashboard always reads from the summary layer — raw data is only touched for drill-downs.

SQLMaterialised summary refresh — runs every 5 minutes via cron
-- Incremental summary refresh
INSERT INTO event_summary (workspace_id, event_type, day, total)
SELECT
  workspace_id,
  event_type,
  DATE_TRUNC('day', created_at) AS day,
  COUNT(*) AS total
FROM events
WHERE created_at > NOW() - INTERVAL '10 minutes'
GROUP BY 1, 2, 3
ON CONFLICT (workspace_id, event_type, day)
  DO UPDATE SET total = event_summary.total + EXCLUDED.total;

Multi-tenancy with Row-Level Security

Every workspace is fully isolated at the database level using Postgres Row-Level Security policies. No application-level filtering needed — the database enforces workspace boundaries on every query, making it impossible for one tenant's data to leak into another. This is enforced even in the Supabase client, where the JWT is bound to the workspace ID.

Next.js 16Full-stack framework, App Router, Server Actions
SupabasePostgres + RLS + Auth + Edge Functions + Realtime
RechartsComposable chart library for time-series and funnel views
TypeScriptEnd-to-end type safety across client and server
VercelDeployment, edge middleware, environment management
Orbit Analytics funnel analysis view

Orbit Analytics funnel analysis view