Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture Overview

At a high level, Nervix has two major halves:

  • a control plane that owns definitions, scheduling, lifecycle, and coordination
  • a data plane that moves records through the runtime graph

The graph itself is built out of persisted NSPL models:

  • SCHEMA
  • WIRE JSON SCHEMA
  • WIRE CBOR SCHEMA
  • WIRE AVRO SCHEMA
  • CODEC
  • RESOURCE
  • RELAY
  • CLIENT
  • VHOST
  • ENDPOINT
  • INGESTOR
  • JUNCTION
  • DEDUPLICATOR
  • REINGESTOR
  • EMITTER

Those models are stored in the registry and scheduled into a DomainSchedule. The schedule says which nodes exist in a domain, which server is primary for each node, and which servers hold replicas. A relay is one of those runtime nodes: it has one owner, and only materialized relay state has scheduler-selected replicas.

The decision layer converts each committed domain schedule into one in-memory typed execution revision, including node identity, placement, branch and schema contracts, resources, source and sink plans, processor programs, and message-error routes. The runtime binds local resources and executes that revision without reading a Model. Execution Plans follows construction, publication, incremental application, rebuilds, and recovery end to end.

Each declared layer module carries a gated nervix::layer source contract alongside its ownership documentation. The compiler uses that semantic owner through aliases, re-exports and source moves. Configuration Models cannot enter data-plane interfaces or bodies; connector engines explicitly declare that they consume plans. General infrastructure, including consensus persistence, may retain Models when its owning contract requires them. Parser definitions belong to the language, edges and harnesses; import and manifest provenance is checked separately before cfg selection. The session command, mutation, transaction and subscription adapters are edges, as are archive section encoding and restore intake. Their consensus and decision dependencies retain those layers’ ownership. Data-Plane Concurrency states the finite compiler rules and their supported effects.

This graph configuration is persisted with strong control-plane consistency. It is separate from runtime execution state and from the hot-path records moving through the graph.

Before a transaction changes that graph, the control plane plans its ordered execution steps and their before/after affected topology. Its typed report separates required pause scopes from actual gate engagement and remains inspectable through commit and retention. Transaction Quiescence And Impact Inspection defines those guarantees.

Each boundary carries its decisions forward as types: absence stays explicit, distinct states carry their own data, and required identities are validated before execution or recovery. The Typed States And Validation Boundaries chapter covers these rules across the language, registry, runtime, connectors, and clients.

The Errors And Diagnostics chapter explains which layer owns each failure, how typed reports cross boundaries, and how runtime and public edges report them.

Consensus access is restricted by operation. Observers can read locally applied state and watch changes. Proposers can also attempt replicated mutations, administrators manage membership and leadership transfers, and protocol receivers apply Raft messages independently of those capabilities. Consumers receive only the capabilities their responsibilities require. Observation does not imply a linearizable read, and proposal authority does not imply that the node is currently leader.

Raft still checks leadership when accepting a proposal. If leadership changes after a command is admitted, the server preserves the leadership-loss result so the client can redirect to the new leader or wait for an election. Long-running transaction commits validate leadership between steps; their replicated progress survives leader loss so the new leader can continue execution. Raft protocol listeners remain available on every live node through elections and membership changes.

The runtime then instantiates that schedule:

  • ingestors attach to external systems or local endpoints
  • relay owners buffer and route records, including fan-out to remote consumer nodes and sessions
  • junctions, deduplicators, and reingestors transform or route records between relays
  • emitters encode records and publish them externally

Ingestors and emitters meet external systems through connector crates. The server composes a validated typed plan with an integration-specific source or sink, and its data-plane host owns intake, routing, buffering, acknowledgements, and lifecycle. The Connector Crates And The Connector Contract chapter defines that boundary, its source and sink families, delivery and commit points, special integrations, and failure semantics. The Ingestors and Emitters manuals define the public NSPL forms.

HTTP Emitter Architecture traces one HTTP request from its validated configuration and Arrow source record through preparation, response classification, retry, acknowledgement, and recovery, with the one- and three-node qualification evidence.

Every expression follows the same one-way conversion. Parsing produces expression Models; registry validation compiles them to check exact types and sensitivity. The decision layer lowers the committed schedule into typed programs, and node installation compiles them against its bound schemas and UDFs. The data plane executes those programs over Arrow batches with a caller-supplied domain timestamp. The VM Functions chapter defines that pipeline, columnar execution and its selected-row conditionals, row and batch errors, kernel and SIMD choices, every function family, branch-local window aggregates and sketches, and how to add a function. Expression Functions owns the public function contracts.

Clock ownership follows the same one-way conversion. NSPL parsing turns PERIOD, SKEW, start timestamps, and rates into validated vocabulary values. The control plane commits one mapping and fenced authority for a paced START. Each data-plane execution binds a capability for the exact domain and generation and obtains one timestamp snapshot before calling an expression engine or a WASM guest. Engines accept that timestamp as input and cannot read actual UTC. Logical deadlines carry their domain and generation; operational deadlines are a separate process-monotonic type whose construction is limited to timeout, retry, and external-I/O owners. Actual UTC enters the data plane through one physical-time owner in the connector contract and is projected into logical time or used by an explicit external observation contract.

The Domain Clock chapter defines the mapping, lifecycle generation, authority fence, progress delivery, local installation, execution snapshots, admission arithmetic, and logical-deadline boundary in detail.

Runtime execution has its own persistence boundary. Selected execution-node state is persisted through periodic snapshots and replication, but in-flight message batches and ACK state are hot-path memory only. Relay buffers, concrete presence, fan-out, and metrics are owner-local and unreplicated; optional materialized records use the relay’s state replicas.

RESOURCE sits between the control plane and the runtime. The control plane numbers each uploaded version and completes it only after every live node has verified and installed the same archive. Every model that uses a resource pins one completed version, and its runtime consumers load exactly that version from their node’s local copy. An upload adds a version and moves nothing; only a model mutation, such as REBIND RESOURCE, changes the version a model binds. A TLS VHOST is one such binding: the HTTPS listener of every node presents the certificate of the version it pins.

The Resource Versions And Bindings chapter defines catalog and store ownership, the version lifecycle, what each binding loads and when, LATEST resolution, rebinding, the DYNAMIC TLS refresh, and failure and recovery.

All node-to-node traffic uses one mutually authenticated TLS 1.3 and HTTP/2 listener. Independent management, command, replication, relay, and bulk pools isolate traffic, while typed operations, bounded payloads, admission quotas, memory budgets, and deadlines keep one workload from exhausting the node. Application health is observed separately from transport connectivity.

The Cluster Interconnect chapter defines peer identity, connection topology, wire contracts, resource isolation, exchange forms, relay delivery and reconciliation, consensus and bulk traffic, domain-clock progress, application health, lifecycle behavior, and observability.

Clients reach the cluster through a separate public boundary. Every node serves the client session protocol: FlatBuffers frames, verified against one public schema and bounded by fixed session limits, over native gRPC and the console’s binary WebSocket. A request identity pairs each reply with its request, while a durable execution reference names a command’s effects across retries, redirects, reconnects, and restarts, so a client recovers an uncertain outcome exactly instead of repeating it. Row subscriptions deliver typed cells encoded directly from Arrow columns.

The Client Session Protocol chapter defines that boundary, its framing, correlation, dispositions, exact recovery, redirect and reconnection, subscriptions, uploads, bindings, and guarantees, and the Client Implementation Manual states what a client implementation must do.

Stopping a node is its own ordered lifecycle. One owner advertises that the process incarnation is terminating, closes public admission, keeps the services admitted work depends on alive while the local graph drains, and only then tears down the node’s tasks, connections, and storage. One physical deadline bounds all of it, and a repeated signal or an expired deadline ends the process the way a crash would.

The Shutdown And Recovery chapter defines stop requests, phases and outcomes, the deadline and exit statuses, cordon versus terminating placement eligibility, intake stop, graph drain and force flush, ownership handoff during shutdown, connector acknowledgement and commit boundaries, terminal teardown, what survives each ending, and restart recovery.

The rest of this section splits control-plane semantics from data-plane semantics because that distinction is fundamental to how Nervix behaves.