Nodes
A node is one process, one identity, and one or more local indexes. It is the only thing in Gnarl that holds data.
Anatomy
| Component | Responsibility |
|---|---|
| Identity | An ed25519 keypair. The public key is the node ID. |
| Store | The local index. Lives beside the data, never leaves the host. |
| Manifest | The signed summary the node is willing to advertise. |
| Policy | Who may ask, what they may ask about, and how often. |
| Peer table | Manifests learned from other nodes, with freshness and health. |
What a node stores
- Its own index, derived from data it can already read.
- Manifests for peers it has heard from.
- Health and latency statistics used for planning.
What a node never stores
- Another node's documents.
- Another node's index segments.
- A copy of the network's state that must be kept in sync.
This is the property that makes the model work: nodes are cheap to add and cheap to lose, because losing one removes exactly one node's answers.
Roles
Any node can play any of these at the same time. They are not deployment types.
Serving node — holds an index and answers queries. The default.
Entry node — receives queries from applications and coordinates fan-out. Any serving node does this; some operators run entry nodes with no local index at all as a query gateway.
Any node already does this. Query coordination is not a deployment mode you turn on — it is what whichever node receives a query does for that query.
Relay — forwards manifests and queries across a network boundary where nodes cannot reach each other directly. A relay sees ciphertext queries and results; it cannot read them.
Relaying is on by default so that home NATs and CGNAT can still join. Point a
node at a specific relay with gnarl start --relay-url <url>, or opt out
entirely with --no-cloud-relay.
Peer classes
A peer is not a machine class. The same node, the same protocol, and the same identity model run everywhere — what changes is how much the peer takes on.
| Class | Platforms | Typical role |
|---|---|---|
| Cloud / server | Linux, Windows Server, Kubernetes | Heavy corpora, widest fan-out participation |
| Desktop | macOS, Windows, Linux | Local archives, always-on workstation peers |
| Laptop | macOS, Windows, Linux | Answers offline, reconciles its manifest on reconnect |
| Mobile | iOS, Android | Collects and answers at the edge, on battery |
There is no privileged tier. A phone's manifest is planned against exactly like a rack's; it simply advertises less and is asked less often.
Mobile and laptop peers add power and connectivity constraints:
A phone runs as an edge peer — gnarl start --edge — which advertises edge
capability, declines foreign primary placement, and uses a longer anti-entropy
interval so the radio is not the cost. Gnarly Edge applies those defaults for
you.
A peer that declines to answer because it is on battery is not an error — the coordinator records it as unanswered and the response reports the coverage.
Sizing
Index size is dominated by the fields you index, not the size of the source documents.
| Corpus | Typical index | Memory |
|---|---|---|
| 10 GB text | 2.5–4 GB | 2 GB |
| 1 TB text | 250–400 GB | 16 GB |
| 100 TB imagery metadata | 3–6 TB | 32 GB |
A node answers from disk with a hot cache; there is no requirement to hold the index in memory.
Lifecycle
gnarl start # run the node in the foreground
gnarl status # node ID, peers, claims
gnarl inspect # ownership, counters, and peers in one view
start runs in the foreground and stops on Ctrl+C. A node that goes away is not
an outage: peers stop getting answers from it and every response says so through
coverage, which is the same path a sleeping laptop takes.