Altering A Running Graph
Nothing built so far required tearing anything down — every step added nodes. ALTER statements
change what already exists: junction logic, relay properties, schemas, ingestor sources, emitter
sinks, stateful processor behavior, reingestor wiring, and generator cadence or routes. Nervix
classifies each validated change and pauses as little as possible — the statement result reports
the executed level
(ALTER Lock And Quiesce Classification):
DYNAMIC— hot-applied; nothing pauses (relay capacity, junction filters and route logic, deduplicator or reordererMAX TIME, emitter flush policy)ENTITY_PAUSE— only the affected node or relay is gated and drained (topology changes, deduplication keys, reorderer ordering, ingestor, reingestor, generator, and emitter reconfiguration, relay materialized state — theALTER RELAYin Generators ran at this level)DOMAIN_PAUSE— domain ingestion stops, in-flight work drains, the new graph is installed atomically, and flow resumes (schema and branching changes)
Before altering anything, SHOW CREATE <kind> <name>; prints the current canonical definition.
Change Routing Logic — Dynamic
Lower the high-value threshold from 1000 to 500. Route changes go through
ALTER JUNCTION; REPLACE ROUTE requires the complete
route body, not a diff:
ALTER JUNCTION route_orders
REPLACE ROUTE TO high_value_orders
INHERIT ALL
SET tier = CASE
WHEN input.amount >= 10000 THEN "vip"
ELSE "high"
END
WHERE output.amount >= 500
FLUSH IMMEDIATE
ON MESSAGE ERROR LOG;
The result reports quiesce level: DYNAMIC — the domain never paused, buffered work stayed in
place, and the very next order is evaluated against the new threshold. Produce a 700-amount
order and watch it reach high_value_out, which the old threshold would have dropped.
Relay capacity is equally uneventful (Altering Relays, capacity semantics under Capacity):
ALTER RELAY orders SET CAPACITY 8;
Evolve A Schema — Domain Pause
Payments gain a method. A codec requires its wire schema to exactly match the internal schema,
so both must change in one transaction — the registry validates the complete candidate graph
before anything applies (Altering Schemas):
BEGIN;
ALTER WIRE JSON SCHEMA payment_wire
ADD FIELD method string OPTIONAL;
ALTER SCHEMA payment_record
ADD FIELD method STRING OPTIONAL;
COMMIT;
This reports quiesce level: DOMAIN_PAUSE: ingestion stops, buffered output is force-flushed (no
in-flight records are lost), the graph is swapped, and flow resumes — there is no user-facing
PAUSE statement, and a drain timeout rolls the whole batch back
(Automatic Model-Alteration Quiescing).
Add the field as OPTIONAL: old payloads without it keep decoding, and the field finalizes as a
typed null. Verify by POSTing a payment with "method":"card" to /payments and watching the
payments relay.
Two rules worth knowing before you lean on this:
- One alteration at a time per domain — a concurrent mutation is rejected with
already has a model alteration in progress, not queued. DROPplusCREATEof the same entity in one batch is compared as one modification — you cannot sneak a schema change past domain quiescing by recreating the relay.
Ingestors and emitters have their own operation sets —
Altering Ingestors (an ingestor’s ALTER repeats its connector
and entity, such as ALTER KAFKA TOPIC INGESTOR kafka_orders, and every ingestor change is
entity-pause) and
Altering Emitters (flush changes are dynamic; sink, client, and
codec changes are entity-pause; source-list membership changes are domain-pause). Processor
operations are covered under
Altering Deduplicators,
Altering Reorderers,
Altering Reingestors, and
Altering Generators.
Next: run the graph on a logical clock in Paced Domains.