Skip to main content
DB
Back homeUse case

Real-time dashboards & user-facing analytics

Serve user-facing analytics from relations that maintain themselves, and push each change to the client as it commits.

The problem

Where the usual stack breaks

  1. 01

    User-facing analytics has a budget a warehouse cannot meet: the dashboard has to load quickly, for many users at once, over data that changes constantly. Running the aggregation on every page load does not scale; running it on a cron and caching the result serves stale numbers.

  2. 02

    The usual fix, a stream processor maintaining rollups into a serving store, adds a second system, a second schema and a freshness gap between the rollup and the source that users notice the moment they act and refresh.

  3. 03

    You want a serving relation that is maintained from the source by change propagation rather than a timer, read as an ordinary table and followed live.

Architecture

How NYXDB does it

A materialized view or a transformation keeps the serving relation current from every committed write. Parameterized materialized views are templates: CREATE MATERIALIZATION freezes one tenant’s arguments into a concrete, continuously maintained instance.

  1. 01

    Define the shape

    A materialized view template with typed parameters, or a keyed target table for a transformation.

  2. 02

    Materialize

    One maintained instance per tenant, from CREATE MATERIALIZATION … OF …; a grouped transformation keeps the totals.

  3. 03

    Propagate (PSI)

    Committed changes reach the subscribers that read them, with no periodic full re-scan.

  4. 04

    Serve

    Dashboards read the instance by name; STREAM SELECT pushes each change to the client.

Examples

In practice

Activity per balance, kept current by a transformation
CREATE TRANSFORMATION balance_activity INTO balances ATTRIBUTE GROUP activity AS
SELECT
chain_id,
recipient AS address,
token,
COUNT(*) AS transfer_count,
MAX(transferred_at) AS last_transfer_at,
MAX(_index) AS activity_index
FROM transfers
GROUP BY chain_id, recipient, token;
Live volume per token, as a query that stays open
STREAM SELECT chain_id, token, SUM(amount) AS volume, COUNT(*) AS transfers
FROM transfers
GROUP BY chain_id, token;

The examples use the same two tables on every page. See the SQL reference for full syntax.

Capabilities

What you get out of the box

Continuous materialization

Materialized views and transformations keep serving relations current.

PSI propagation

Every committed write is published once and delivered to each subscriber.

Per-tenant instances

One maintained instance per tenant, from a parameterized template and CREATE MATERIALIZATION.

Restart contract

Materialized views reseed from a source snapshot after a restart.

Maintained aggregates

Counts, sums, minimums, maximums and averages stay current, maintained by transformations.

Live push

UI updates arrive without polling, with STREAM SELECT.

Learn more

Dashboards that are live, not polled

Materialize a serving relation and stream it to the client.