Peer to peer

Across any network. No server holding the truth.

Most of what is called peer to peer keeps a server behind it — to introduce the devices to each other, to hold what they agree on, and to pass messages along when they cannot reach each other directly. Take the server away and the application stops.

Here every device keeps its own journal of what happened, and devices find each other by a cryptographic identity rather than by an address. The network helps them find a path to each other. When a direct path isn't available, a relay forwards packets it cannot read.

No server holds the truth, because the truth is already on the devices.

What it does

  1. Devices that find each other by identity

    A device is its public key, not its address. Nothing has to be opened on a router, and no tunnel or private network has to be arranged first.

  2. Connections that survive a change of network

    Moving from Wi-Fi to mobile data changes the path, not the connection. The device keeps its identity and the session carries on.

  3. A room with no internet still works

    Devices on the same local network reach each other directly. Nothing outside the room is required for the room to function.

  4. Late arrivals arrive current

    A device that joins after things have happened receives them, in order, and is immediately up to date.

  5. Offline is replay, delayed

    A device that was away receives what it missed in the order it happened. There is nothing to reconcile by hand, because what travels is what happened rather than a snapshot of state.

  6. One authority where it matters

    Each decision has a single writer, so two devices cannot sell the same item or award the same prize.

  7. Encrypted end to end, even through a relay

    Connections are authenticated and encrypted between the devices themselves. A relay that carries them forwards packets it cannot read.

  8. The same logic in an app and in a browser

    The rules run unchanged in a native Android app and, compiled for the browser, in a web page that installs like one.

Where it fits

Three examples. What they have in common is a shape, not an industry: a group of devices that has to agree on something while the network cannot be relied on.

Live events in a venueRun

Draws, raffles, auctions, quizzes, votes. The room is the network, and the evening does not depend on anything outside it.

Pop-up sales and markets

Several sellers and one inventory, with no two devices able to sell the same item.

Field work with patchy coverage

Teams keep working through dead zones and catch up, in order, when a path comes back.

These are examples and not a list. The capabilities above are general; what changes from one case to the next is how much of the network you can count on.

What has been run

An evening across four homes.

On 23 September a live bingo round ran with players joining from their own homes, each behind a different router, and the organizer running in an emulator on a PC. Every draw reached every player. Nobody opened a port, installed a tunnel or arranged a private network.

During the round, one player switched between home Wi-Fi and mobile data and came back in as the same device, with the same cards. Nothing was lost: her cards were hers and the draws were where they belonged, because each phone keeps its own journal and receives what happened, not a copy of the state. The organizer's log shows one identity throughout, not two phones: the transport moved the path, so there was nothing to record. Nobody else in the round noticed.

Nobody else in the round noticed.

When two devices cannot find a direct path, a relay introduces them. In that round it was a public one, run by somebody else: it could not read what it carried and kept none of it. It does not have to be somebody else's — a relay can be your own.

What changes when a phone moves from Wi-Fi to mobile dataA remote player's phone carries an identity that does not change. Its address changes from home Wi-Fi to a carrier address, and the path it takes to the organizer changes with it, passing through a relay that acts as a meeting point. The connection itself is one unbroken line from the player to the organizer.Remote playeridentityhome Wi-Ficarrier addressthe address changesrelaymeeting pointsame connection, new pathOrganizer
Measured, not projected

What was measured, and on what.

Ten results, each with the device it was taken on and the day it was taken. Three were taken on emulators and two come from a prototype rather than the published web client, and each of those says so.

WhatResultMeasured on
Phones on different home networksFour phones on four networks over QUIC through iroh, with no port opened on any routerAndroid phones · 23 Sep 2026
Longest single connection in a live round22 minutes, through all 69 drawsAndroid phone on a home network · 23 Sep 2026
Wi-Fi to mobile dataEmulatorNext event in the same second; six seconds after two switches in a rowAndroid emulators · 22–23 Sep 2026
A room with no internetEmulatorEvents delivered in zero to two seconds over direct pathsAndroid emulators · 23 Sep 2026
Back after an outageEmulatorReconnected by itself in 10 to 51 secondsAndroid emulator · 23 Sep 2026
The browser as a peerPrototypeEvents pushed over a channel the browser opens outward, 58 to 237 ms round tripGalaxy A54, Chrome 153 · 24 Sep 2026
The browser back from the backgroundPrototypeReconnected 4 and 12 seconds after returning to view — the handshake itself takes half a second — and received the 13 and the 8 draws it had missedGalaxy A54, Chrome 153 · 24 Sep 2026
The web clientInstalls as an Android app over HTTPSGalaxy A54, Chrome 153 · 24 Sep 2026
The web client with its host unreachableOpened from its cached copy and kept talkingDesktop Chrome 153 · 24 Sep 2026
First visit of the web client11.6 MB gzipped — 9.6 MB of it the runtime and the engine, and 0.15 MB the page24 Sep 2026

Every row above has a raw output behind it, with the hour it was taken and the command that produced it. Those are being published alongside the code.

Three layers

  1. The rules

    The domain: the game, the sale, the prize. Plain .NET, with no reference to Puppeteer. It knows nothing about devices or networks.

  2. The subjects

    Puppeteer gives each subject an identity and a journal. One subject writes each decision; its replicas receive that history and replay it. Subjects tell each other facts, and each applies them in its own journal.

  3. The transport

    An adapter carries those messages. Here it is QUIC over iroh: it dials a device by its public key, tries a direct path first and falls back to a relay. Elsewhere the same model runs over sockets on a local network or a broker in a data center.

The transport can change without changing the domain or the subject model. In September it did: the transport moved from HTTPS between phones to iroh, and the game did not change a line. Its 432 domain tests never mention a network.

iroh is the adapter we chose for phones across networks. The adapter is ours; the model does not depend on it.

What to plan for

  • A browser cannot accept incoming connections. It has to reach outward and keep a channel open.
  • Mobile operating systems freeze an app in the background within seconds, so the design has to assume reconnection and catching up rather than a connection that stays.
  • Across networks, devices need a relay when no direct path can be found — a public one or your own. Inside a single room they need none.
  • Safari on iPhone will not let a page served over HTTPS reach devices on the local network.
  • The behaviour is proven. Scale is the next question.

Questions

How do I build a peer-to-peer app without a server?
Give every device its own journal and let the devices exchange facts directly. One subject writes each decision and its replicas share the history, so no server has to hold the truth.
Can peer-to-peer apps connect across different networks without port forwarding?
Yes. Devices identify each other by a public key rather than an address and connect over QUIC through iroh, with NAT traversal first and a relay that cannot read the traffic as the fallback.
What happens when a phone switches from Wi-Fi to mobile data?
The connection continues on a new path. The device keeps its identity, so the session migrates rather than being re-established.
Can a peer-to-peer app work on a local network with no internet?
Yes. Devices in the same room reach each other over direct local paths, and nothing outside the room takes part.
How do devices catch up after being offline?
They receive what they missed, in the order it happened. A device that joins late receives everything that already happened.
Is peer-to-peer traffic encrypted when it goes through a relay?
Yes. The connection is authenticated and encrypted end to end between the devices, and the relay only forwards packets it cannot read.
Can a web browser be a peer?
Partly. The same logic runs in the browser and the page installs like an app, but a browser cannot accept incoming connections — it has to open a channel outward.

If this bears on what you are building

Tell us which part.

Start a technical conversation