Architecture

What this puts on your network, and what it talks to. The whole platform is one stateless container and one Supabase project; everything else is an outbound call to somewhere you already trust.

Your infrastructureBrowsersyour usersLoad balanceroptionalAgentSwarmsstateless Node containerSupabasePostgres · auth · storageModel providersOpenRouter, OpenAI, Anthropic, …Your databases22 warehouse connectorsSaaS APIsSheets, Stripe, Shopify, CRMsRLS-scopedyour keysread-onlyread-onlyScale horizontally — no sticky sessions, no local state

Deployment

One container

A single stateless Node process, shipped as a Docker image. DEPLOY_TARGET=node is the primary target; docker compose up is the documented path.

One database

A Supabase project you create and own — Postgres, auth and object storage. Migrations are applied with the Supabase CLI. Nothing else is required to run the platform.

Scales horizontally

The container holds no session state, so it runs behind an ordinary load balancer with no sticky sessions. Background work is coordinated through the database with a cross-instance lease, and can be disabled per-instance with DISABLE_INPROCESS_SCHEDULER so one node owns it.

Health endpoint

/api/health for liveness and readiness probes.

Egress

Every outbound destination, and nothing else. Useful if you are writing firewall rules.

Model providers

Outbound HTTPS to whichever providers you configure, using your keys. Prompts and completions do not pass through any vendor of ours.

Your data sources

Outbound to the databases, warehouses and SaaS APIs you connect. Database drivers use their native ports; everything else is HTTPS. Connectors are documented to use read-only credentials and every query path rejects anything but SELECT-class statements.

Private networks are reachable

A warehouse inside your VPC is a normal deployment. Outbound requests are screened against cloud metadata and link-local addresses, but private ranges are deliberately allowed.

No call-home

No telemetry, no licence check, no usage reporting. Nothing is baked in: the cookie banner's optional analytics exist only if you configure your own VITE_GA_ID, and with it unset no banner is shown at all. An air-gapped deployment reaching only your own model endpoint is a supported configuration.

Scale

What is bounded, and by what. Full numbers and the environment variables that change them are in docs/SCALE_AND_LIMITS.md.

Aggregation runs in your warehouse

Semantic-layer queries and linked warehouse tables compile to SQL that executes where the data lives, so a billion-row GROUP BY is your warehouse's work and only the grouped result travels. Result sets are capped (1,000 rows by default, 5,000 hard ceiling, 60s timeout) — that bounds what comes back, never the table.

Prep folds into the warehouse when it can

When every source in a flow is on one connection and every step is expressible in that dialect, the whole pipeline becomes one SQL statement run inside the warehouse — and the fold is proved against the real warehouse before it is trusted, so a refusal costs speed, never correctness. Mixed or non-foldable flows run locally instead, and the UI says which.

Local datasets are laptop-scale, on purpose

Uploaded and synced datasets are DuckDB tables capped at 500,000 rows and 100 MB by default. They exist for CSVs, samples and SaaS syncs. Past a few million rows, link the warehouse table rather than importing it.

Dashboards default to a cached snapshot

A warehouse-backed widget stores at most 500 rows so shared links render instantly. A chart that sums raw rows in the browser therefore shows a partial total if the refresh hit that cap — it is marked truncated rather than shown as confident. Aggregate pushdown (GROUP BY in SQL) or direct query mode gives the complete number.

State and backup

What has to survive, and what is safe to lose.

Everything durable is in Postgres

Agents, swarms, datasets, dashboards, traces and audit events. Back up the Supabase project and you have backed up the platform.

Object storage

Uploaded documents, generated files and the columnar dataset mirrors live in Supabase storage buckets.

Local disk is a cache only

The Parquet mirror cache is on local disk and is disposable — losing it costs speed, never data. Give it a real volume on a container host so it survives restarts.

Full deployment options and environment variables are in docs/DEPLOYMENT.md; every row, timeout and concurrency cap is in docs/SCALE_AND_LIMITS.md. See also Security and Licensing.