One machine on eighteen nodes
Most of this documentation was written as if there were one server. There isn't. There are eighteen, and they behave as one machine — not because they share a database, but because they run the same code over the same arithmetic and merge a single append-only log.
Ask any of them for the roster and you get the same answer:
curl -s https://zeq.me/api/mesh/peers \
| python3 -c "import sys,json;d=json.load(sys.stdin);print(d['self_node'],'+',len(d['peers']),'peers =',1+len(d['peers']))"
# machine-zeqme + 17 peers = 18
Measured 2026-09-03 across every node: 1 + 17 = 18 on all eighteen, and every entry carries
tcp_port 18870 — the mesh port they dial each other on.
What a node is
A node is a whole machine, not a replica of one. Each has:
- its own Postgres — one database per node, same schema, different rows;
- its own Redis;
- its own genesis zeqond — the tick that node was born on. These genuinely differ:
2296062064onzeq.dev,2301090211onzeqproof.com,2296201458onzeq.me; - its own Ed25519 node identity — a unique
nodeIdandpublicKeyHex, published atGET /api/node/status, which is what every signed node-to-node request is checked against; - the same golden image — the same built
server.mjs, from the same commit.
curl -s https://zeqproof.com/api/node/status | python3 -m json.tool | head -20
The genome is byte-identical, and that is a shipping gate
"Same code on every node" is not a slogan here; it is a check that has to pass before a deploy is
considered done. The gate is infra/p80/verify-fleet.sh, and it asserts that three values each
have exactly one distinct value across all eighteen nodes:
| Value | Where it is read | Measured 2026-09-03 |
|---|---|---|
| dist md5 | md5sum /app/apps/zeq-dev/dist/server.mjs inside each container | one distinct value |
| git sha | GET /api/health → git_sha | 803c02a3a510023f5986cba891e3ab174a0f0f8f ×18 |
| treasury pool | GET /api/transparency/now → snapshot.poolBalance | 436469 ×18 |
Anything not identical is printed rather than summarised, and the script ends in FLEET: PASS
or FLEET: FAIL. You can run two thirds of it yourself:
for h in zeq.me zeqsdk.com hulyapulse.com zeq.cash kinematicspectrum.com zeqond.com \
zeqproof.com hulyas.org zeqstate.com hulyafield.com zeqapi.com 1.287hz.com \
zeqvm.com machine.zeq.digital zeq.dev hulyasmath.com zeqenvelope.com machine.zeq.dev; do
curl -s "https://$h/api/health" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['git_sha'])"
done | sort | uniq -c
# one line = the fleet is on one commit
# same shape for the pool — must collapse to a single number
for h in zeq.me zeqproof.com zeqenvelope.com hulyafield.com; do
curl -s "https://$h/api/transparency/now" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['snapshot']['poolBalance'])"
done | sort -u
# 436469
Be honest about the window. A deploy rolls node by node, replicas first, and while a wave is
in flight the fleet is deliberately not identical. During the 2026-09-03 wave the git_sha sweep
above returned two values — fourteen nodes on 803c02a3… (built 10:25:03Z) and four
(zeqproof.com, hulyafield.com, 1.287hz.com, zeqenvelope.com) already on fdb19076… (built
10:42:32Z). The pool stayed at one value the whole time. The gate is what closes the wave, not
what runs during it.
Shared versus per-node
This is the distinction the rest of the documentation should have started with.
Shared — computed identically, or merged from one log
| Thing | How it is shared | Check it |
|---|---|---|
| The WORM issuance spine | an append-only, hash-linked log; the federated sub-chain replicates node to node | GET /api/worm/replication |
| The treasury / compute pool | a projection of that spine — same inputs, same arithmetic, same number | GET /api/transparency/now |
| Network genesis | network_genesis_zeqond = 2301090211, one distinct value ×18 | GET /api/transparency/now |
| The operator registry | registry_version = 263fb257df4e…4796, one distinct value ×18 | GET /api/identity |
| The issuance arithmetic | a pure function of the zeqond — no coordination at all | GET /api/mesh/issuance/at?z=… |
That last one is the cleanest demonstration that this is one machine. Ask two nodes what the coin for a given tick is:
for h in zeq.me zeqproof.com; do curl -s "https://$h/api/mesh/issuance/at?z=2301711961"; echo; done
{"ok":true,"node":"machine-zeqme","z":2301711961,"window":2301711961,
"key":"zeq-issuance-v1:w2301711961","rate":0.999999999999,
"amount":"0.999999999999","phase":0.9999813437114706}
{"ok":true,"node":"machine-zeqproof","z":2301711961,"window":2301711961,
"key":"zeq-issuance-v1:w2301711961","rate":0.999999999999,
"amount":"0.999999999999","phase":0.9999813437114706}
Every field matches except the node's own name. The rate is 1.287 × 0.777000777, derived from
the kernel constants rather than hardcoded — which is why it reads 0.999999999999 and not 1.
Two nodes cannot disagree about a pure function of a shared counter, so there is no consensus,
no voting and no quorum in the issuance path. See
the spine and replication.
Per-node — created here, stored here, readable only from here
Your machines, envelopes, coins, pages and vault secrets live on the node that created them. So does your plan. None of it replicates.
The numbers make this concrete. The same sweep that returns one pool balance returns eighteen different local states:
| Value | Across the eighteen |
|---|---|
machines (GET /api/mesh/self) | 53 → 266 |
ledger_count (GET /api/worm/status) | 7 → 153,689 |
ledger_root | eighteen different roots |
snapshot.totalMinted | 617,557 → 1,466,159 |
node genesis_zeqond | eighteen different ticks |
The federated sub-chain carries network-level events — issuance, pool flows, machine genesis, precision seals. It does not carry your envelope contents, your coins, your pages or your vault. Those rows are marked private at insert and never enter the wire (see what actually travels).
The consequence is blunt: while a node is down, the data created on it cannot be read from anywhere else. There is no failover for private state. What the mesh gives you is the ability to find out where your data is — see your identity and your home node — not the ability to read it from somewhere else.
Two roster endpoints, only one of which you want
GET /api/mesh/peers— the livemesh_peersregistry. This is the roster: 18 entries, node id, base URL, TCP host and port. Use this.GET /api/mesh/status— the older gossip-mesh counter, fed from the staticZEQ_MESH_PEERSenvironment list. Onzeq.metoday it reportsmeshSize 4,activeNodes 3,lastGossip 0. That is a legacy roster, not the fleet.GET /api/worm/quorumreads the same static list, which is why it reportsmember_count 4rather than 18.
GET /api/mesh sits between the two: it returns each node's registry_version, git_sha,
machines and latest_zeqond, but its liveness fan-out is unreliable from outside the fleet — a
call to zeq.me returned alive: false for thirteen nodes that all answered a direct request
seconds later. Trust the direct sweep over the fan-out.
What this frame changes elsewhere
- The lattice describes proofs travelling while state stays put. That is still true for private state, and the "isn't replicated or gossiped" line on that page is corrected in detail on the spine page.
- The economy mints from one place, not from every node — see the issuer and failover.
- Sign-in works on any node, because a ZID is a deterministic function of your equation. Your data does not follow you.
Read next
- The issuer and failover — exactly one node seals issuance, and what happens when it stops.
- The spine and replication — what travels between nodes, and how a receiver verifies it instead of trusting it.
- Your identity and your home node — finding your state across eighteen nodes.