DB
Back homeUse case

HTAP & operational analytics

Run transactional point access and analytical scans on the same data. The physical layout is a per-table choice — not a second system to ETL into.

The problem

Why this is hard today

The HTAP tax is two databases. A row store answers point reads and writes fast but scans slowly; a column store scans fast but is a poor fit for single-row access. So teams run both and ship rows between them with CDC and ETL — paying for the lag, the duplication, and the reconciliation jobs that keep them honest.

The copy is where correctness goes to die: the analytical side is always minutes behind the operational side, dashboards disagree with the application, and "how many active accounts right now" returns a different number depending on which store you ask.

What operational analytics actually needs is one engine where a row can be written and pointed-at transactionally and scanned analytically — where the storage layout is chosen per table to fit the access pattern, not bolted on as a separate system.

Architecture

How NYXDB does it

Every table picks its physical layout independently (ADR-001, “HTAP via per-table storage layout”): row layout for OLTP point access, columnar for OLAP scans — the same catalog, the same SQL, the same transactions, with nothing shuttling rows between them.

  1. 01

    Choose layout

    A keyed, row-layout table serves single-row reads and writes; an append, columnar table serves analytical scans — each set with one SETTINGS clause.

  2. 02

    Commit under MVCC

    Writes commit under MVCC (ADR-017) with the WAL sequence as the version clock — readers see a consistent snapshot, writers never block them.

  3. 03

    Read your writes

    The operational read reflects the write that just committed — there is no CDC lag to an analytical replica.

  4. 04

    Scan analytically

    Columnar, SIMD-vectorized expression execution scans the same data for aggregates and reports.

Real SQL

In practice

Row layout for OLTP, columnar for OLAP
-- Operational: keyed, row layout, memory-resident — fast point access
CREATE TABLE accounts (
id UInt64 NOT NULL,
balance Int64,
status String,
PRIMARY KEY (id)
) SETTINGS mode='keyed', layout='row', storage_policy='memory_data';
-- Analytical: append, columnar — fast scans over history
CREATE TABLE ledger (
account_id UInt64 NOT NULL,
amount Int64,
ts DateTime
) SETTINGS mode='append', layout='columnar', index_granularity=2048;
Point access on the operational table
SELECT balance, status FROM accounts WHERE id = 42;
Analytical scan over the same data
SELECT account_id, count() AS txns, sum(amount) AS net
FROM ledger
GROUP BY account_id;

Every statement follows the engine’s own test SQL shapes. See the SQL reference for full syntax.

Capabilities

What you get

Per-table layout

Row layout for point access, columnar for scans — chosen per table (ADR-001).

MVCC snapshot isolation

Snapshot reads at a WAL sequence; writers never block readers (READ COMMITTED default, ADR-017).

Read-your-writes

The operational read sees the write that just committed — no replica lag.

Vectorized scans

Columnar, SIMD-vectorized expression execution for heavy analytics.

One catalog

Operational and analytical tables share one schema and one SQL surface.

No ETL

Retire the CDC pipeline and the second store.

Proof

Measured on the vetted benchmark lane

Measured on Apple M4 Max (dev), macOS — server-class validation pending. Release build, median of 5, commit-pinned (d4a3885b, 2026-07-07). Ingest figures are engine-side. See the full benchmark suite.

One engine for writes and analytics

Model an operational table and an analytical table, and query both.