Skip to main content
DB
Product

Keep state, history and live views in one engine

NYXDB is a SQL database. Your tables stay exact as writes land and remember every version, and the derived tables, materialized views and live queries you define are maintained from every committed write, with no stream processor in between.

Capabilities

Store, version, derive, stream and share, in one engine

Six capabilities in one process. Select one to see what it changes for you, and the terms the docs use for it.

Choose per table whether it keeps every row, only the latest state per key, or the latest state plus every accepted version. When writes arrive out of order, the engine settles which version wins.

MODE APPEND
keeps every row
MODE UPSERT
keeps the latest row per key
MODE VERSIONED
keeps the latest row and every accepted version
VALID BY · REVISION BY
decide which version wins
Tables · Versioned historyRead the concept

How it works

From your first table to a live view in three statements

Plain SQL, start to finish. The same two tables run through every example on this site and in the docs.

01

Create a table

Decide what each table remembers: every event, the latest state per key, or the full history of every change. Shard it by a key and pick the storage layout that fits how you read it.

an append table of transfers
CREATE TABLE transfers (
chain_id UINT16 NOT NULL,
token STRING NOT NULL,
sender STRING NOT NULL,
recipient STRING NOT NULL,
amount UINT256 NOT NULL,
transferred_at DATETIME64(3, 'UTC') NOT NULL,
_index UINT128 NOT NULL
)
MODE APPEND
SHARD BY (token) SHARDS AUTO;
02

Follow it live

Put STREAM in front of any query and it stays open: you get the answer now, then every change to it as new writes land. No polling, no second system.

a continuous grouped query
STREAM SELECT chain_id, token, SUM(amount) AS volume, COUNT(*) AS transfers
FROM transfers
GROUP BY chain_id, token;
03

Keep a derived table current

Describe the table you wish you had as a query. A transformation keeps it up to date from every committed write, so the aggregate, the enriched view or the balance is always ready to read.

a fold into one attribute group
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;

The usual stack vs NYXDB

Everything the glue did, done by the engine

Line by line: what you stop running, and what you get instead. Each row restates a guarantee the docs make.

The usual stack compared with NYXDB, one concern per row.
What you readA cached copy that lags its source by a hop.The table itself, fresh on every read.
Derived stateComputed by a stream processor, then reconciled against the store.Kept exact by the engine from every committed write.
SchemasDeclared once per system and kept in step by hand.Declared once, in the table.
Yesterday’s stateRebuilt from logs or snapshots when you need it.Any versioned table, read as it stood at a past commit.
What you runA database, a queue, a stream processor and a cache.One process, a configuration file and a data directory.
What you writeA dialect per system and an API per hop.One SQL dialect for tables, derived tables and live queries.
When a write shows upEventually, once the pipeline catches up.On the next read, and once to everything derived from it.

Guarantees, stated on the consistency page. Nothing in this table is a measurement.

Consistency in the docs

Connect from anywhere

Reach the node from wherever your code runs

HTTP for sign-in, one-shot statements and bulk rows; a WebSocket session for everything that stays open; and a TypeScript client that covers both, in the browser and in Node.

HTTP

Sign in, run a statement, load rows

Exchange a password or an API key for a session, send one statement and receive its whole result, or push a bounded batch of rows to one table. Plain HTTP, JSON in and out.

the routes
# a bearer becomes a session
POST /auth/session
# one statement, the whole result
POST /sql
# a bounded batch of rows to one table
POST /write/batch
WebSocket · nyxdb.public.v1

One connection, many requests, live results

Open a session once and run finite reads and streaming queries side by side, each tagged by its request id. The server sends only what your client has asked for, so a slow consumer is never flooded and a long stream never blocks a quick read.

the frames
# the session token travels in the first frame
GET /client
OpenSession → ExecuteSql → ResultBatch → Completed
# a streaming query on the same connection
ExecuteSql → ContinuousOpened → ContinuousResult …
# flow control
Demand · ContinuousDemand · Cancel
@nyxdb/client

Lossless values, in the browser and in Node

The TypeScript client speaks both transports: it signs in, opens sessions, sends write batches and resumable bulk loads, and multiplexes cancellable queries over one socket. Integers stay exact, decimals keep their precision and scale, and binary values arrive as bytes.

the types
# one package, both transports
@nyxdb/client
# every value arrives lossless
integers → bigint
decimals → precision and scale kept
binary → Uint8Array
# a password or API key is sent only over https, or to loopback

Attribute groups

One writer per attribute group

Let one pipeline own the balance and another own the activity counters on the same row, with neither able to overwrite the other. A grouped fold writes just one attribute group of a versioned table, each definition writes only what it does not read, and the engine reports lineage per group.

a fold into one attribute group
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;

Frequently asked questions

The questions a technical buyer asks first, including the awkward ones. Anything else is answered in the docs, or in the open on GitHub.

A SQL database. Your tables hold exact current and versioned state, and the derived tables, materialized views and streaming queries you define are kept current from every committed write, inside the engine. There is no separate stream processor to run.

From a fresh node to a live view

Start a node, create a table, and watch a streaming query follow it. The docs take you from install to your first self-maintaining derived table.