Resonator LLC
2026-08-22
Protocol

SQLite databases talking to each other

A Resonator node is a SQLite database, a peer-to-peer endpoint, and a SPARQL engine in one process. The interesting part is not the database — it is what the databases say to each other.

Text

Strip away the vocabulary and a Resonator node is three things running in one process: a SQLite database, an iroh peer-to-peer endpoint, and a SPARQL engine that executes over that SQLite. There is no server in the picture, and no account. A node’s identity is an ed25519 keypair, and two nodes that have each other’s public key can talk.

That much is unremarkable. Plenty of things embed SQLite. What decides whether a network is worth building is the part in the middle: what exactly goes over the wire.

The first draft, and why it was wrong

The original design put SQL text inside a Rust struct and sent that. It worked, and it was a dead end, because it quietly bound the whole network to three accidents at once:

  • SQLite’s five storage classes became the network’s value model.
  • SQLite’s dialect of SQL became the only payload anyone could parse.
  • Rust’s serde became the de facto schema language.

The test that kills it is simple. A Postgres node wants to join. Under that design it cannot even read an incoming request, let alone answer one. The network would have been a SQLite network wearing a protocol.

Splitting the two things that were fused

The ambition is symmetric heterogeneous peers: a Postgres, DuckDB or Mongo node joins, answers queries through its own authenticator, and asks questions of its own. Getting there means separating two concerns the first draft had welded together:

  • The wire language, which every peer must speak, and which therefore has to be engine-neutral.
  • The query payload, which is irreducibly engine-specific and should be left that way.

The wire language is RDF. Every message on the network is an RDF object serialized as Turtle. A query is also an RDF object — one that carries its engine-specific text along as a literal:

[] a rsntr:Query ;
   rsntr:mod    "sql-sqlite" ;
   rsntr:signal "SELECT name, seen FROM _peers ORDER BY seen DESC" .

Peers speak the payload families they understand, and render what they can. A node that has no idea what sql-sqlite means can still parse the envelope, see that this is a query, and route or refuse it intelligently.

The deliberate non-goal is worth stating: we are not translating every engine into one universal query language. That path is where data-integration projects go to die.

This is not a new idea

Putting a query inside a statement has precedent we leaned on rather than invented:

  • SPIN represents SPARQL queries as RDF objects — a node typed as a select query, carrying its query text as a property. Our envelope is that shape with the engine generalised.
  • R2RML, a W3C recommendation, holds a valid SQL query as a literal in Turtle.
  • Resonator’s own earlier transport already turned every network event into a one-line Turtle statement and accepted Turtle commands back — no command vocabulary, only RDF flowing in and out.

Where the RDF starts

The handshake has two layers, and only one of them is RDF.

Layer 0 — transport. iroh does its work over QUIC: it proves both identities and opens a channel. No RDF is involved here.

Layer 1 — envelope. From the first byte of application data onward, everything is RDF objects, including the hello exchange and the admission handshake that decides whether a stranger gets to ask anything at all.

So “everything is RDF” is precise rather than rhetorical: it begins the moment the cryptography has finished.

Where it actually is

v3 is a Rust workspace. It builds the core crates, rsntr (a console tool meant to be comfortable for shell pipelines and for LLM agents), and a Python package usable from a notebook. The node is AGPL-3.0-only; the Python package and the mod PDK are MIT, so writing a client never drags you into the copyleft.

Honest about the moving parts: iroh is the third reconsideration of the base transport, and it sits behind a transport trait precisely because Bluetooth and radio should be able to take its place later. The envelope is the part we expect to outlive the transport under it.

Source and documentation live at resonator.network.

◀ All posts