Peer-to-peer mesh networking

Every device relays traffic for the others, so coverage grows with density instead of a tower. DORS, our transport layer, runs this mesh over Bluetooth LE and WiFi Direct on a network that has reached 350,000+ devices.

Diagram: a peer-to-peer mesh network failing over from internet to Bluetooth LE and WiFi Direct, relaying an encrypted message between two phones through a relay node with multi-hop routing, acknowledgment, and deduplication.

The internet path drops, and the message reaches unit-19 over two mesh hops.

5transports behind one API
8hops maximum per route
100 MBfiles over the mesh
350,000+devices reached to date

What is peer-to-peer mesh networking?

Infrastructure is a single point of failure. In a conventional network every device talks to a tower, an access point, or a server. When that fails or saturates, every device attached to it goes silent, however close they are to each other.

A mesh removes the middle. Devices connect directly to their neighbours and forward traffic for one another, so a message reaches a device that was never in radio range. Coverage is the union of every radio, and it grows with every device that joins.

It heals itself. When a node drops out, traffic reroutes around it. A mesh needs no infrastructure, which makes it the answer where towers cannot exist: in disaster zones, underground, in the air, or under deliberate shutdown.

Five transports, one switch

DORS, the Dynamic Offline Relay Switch, is the transport layer we built for Offline Protocol. It treats five radios and networks as one pool and moves every message to the best path available at that moment.

The transports

Bluetooth LE
Default

The energy-efficient backbone of the local mesh: peer discovery and small messages at very low power, on every device by default.

WiFi Direct
Android

High throughput for bulk data and chunked file transfer when both ends support it. DORS escalates BLE to WiFi Direct under load.

Internet
Backhaul

A WebSocket path to a server, treated as one more transport. Losing it triggers failover, not an outage.

Reticulum
Long range

A long-range fallback over an external Reticulum daemon, weighted for reliability and energy when local radios cannot reach.

Nostr
Relay

A fallback over Nostr relays with automatic reconnection, so messages still move when only relay infrastructure is reachable.

How a path is scored

  1. ObserveEvery enabled transport reports seven live factors: signal strength, proximity, bandwidth, congestion, energy, reliability, and load.
  2. WeightEach transport weights those factors differently. Bluetooth LE leans on energy, WiFi Direct on bandwidth, Reticulum and Nostr on reliability.
  3. ScoreThe weighted factors become one score per path, from 0 to 100, recomputed continuously as conditions change.
  4. SwitchTraffic moves to a rival path only when it clears the thresholds below, so the mesh never flaps between transports.

Illustration: a scoring matrix of five transports against seven factors, each cell a bar for that rating, with the weighted score at the end of each row. WiFi Direct leads at 91 and is active; the internet is down at 0. Hovering a factor highlights its column.

Hover a factor to see what it measures.

When it switches

15 ptsa rival path must lead by this margin before a switch
20 scooldown between switches
8 sstability window for the current link to settle
-85 dBmsignal floor below which a failing link is abandoned
// Defaults that keep transport switching stable
const dors = {
  switchHysteresis: 15.0,    // min score gap to switch
  switchCooldownSecs: 20,    // spacing between switches
  stabilityWindowSecs: 8,    // settle before switching
  rssiSwitchThreshold: -85,  // dBm, switch on poor signal
};

Under the hood

The mechanics beneath the API, each verified against the SDK.

Clusters, bridges, and multi-path routing

Member role
Connections inside a cluster of nearby peers carry traffic within the group.
Bridge role
Connections that link two separate clusters. Bridges stitch isolated pockets of devices into one routable network.
Connection budget
Each device holds about four peers, scoring every candidate on RSSI, free slots, uptime, battery, stability, and load.
Self-rebalancing
The budget rebalances roughly every 15 seconds, and candidates that would bridge clusters get a scoring bonus, so the mesh actively unifies itself.
Battery-aware relay
Well-charged devices take on relay duty and devices low on energy shed it, so the mesh balances its own load across the fleet.
Gradient routing
A message forwards toward the few best paths at once, not one pre-computed route, so a link that drops mid-flight never strands it.
Exactly-once delivery
An 8-hop TTL, acknowledgment, retry, and deduplication give a message many ways to arrive and exactly one delivery when it does.

Bluetooth mesh and WiFi Direct on ordinary phones

No special hardware
The phones people already carry ship with BLE and WiFi Direct radios, and the SDK turns those radios into mesh links.
Bluetooth LE
Handles peer discovery and small messages at very low power.
WiFi Direct
Carries bulk data, including chunked file transfer up to 100MB, when both ends support it. On Android 10 and later the SDK can form the group itself, with no system dialog. iPhones have no WiFi Direct, so between iPhones the same transport runs over the Network framework, on the local network or AWDL.
Coverage is the fleet
Every device that installs an app built on the platform becomes a relay, so density in a stadium, warehouse, or staging area translates directly into throughput and reach. In production that is 350,000+ devices reached in 140+ countries and 11,500+ local networks active this month, grown on product pull alone.
No base station
Nothing to deploy and no gateway to keep powered. The network is the devices.
One npm install
A TypeScript API in the React Native SDK over a Rust core, with encryption, retry, and multi-hop routing as the default path.

Reliability below your code

Confirmed, not fire and forget
A message is done when an acknowledgment comes back from the recipient and message_delivered fires with latency and hop count. The ACK timeout is about 10 seconds, with up to 1,000 acknowledgments tracked in flight.
Backoff that respects the link
Retries start at 1 second and double to a cap of 5 minutes, for up to 10 attempts, so a flapping peer is retried quickly at first and then patiently.
An outbox with a memory
A message lives in the persisted outbox for up to 7 days. A peer that walks back into range within that window still gets the message it missed.
Parked, then re-driven
A message with no path is parked rather than failed: probed on every carrier with a backoff from 15 seconds to 10 minutes, and re-driven the moment a peer reappears or a link returns.
Safe to relay
Each device deduplicates by message id, about 1,000 recent ids with a one-hour retention, and every message carries an 8-hop TTL, so multi-hop forwarding processes a message once and cannot loop the mesh.
Encrypted by default
Sessions use MLS (RFC 9420) with Ed25519 identities. Relay nodes forward ciphertext, and keys never leave the device.
A clean contract
Your application sees sent, then delivered or failed, with the reason and the retry count attached when the budget is exhausted. Every setting above is tunable through ReliabilityConfig.

Files over the same mesh

One call to send
sendFile takes a file path, a recipient, and an optional name, and returns a file id. The file moves device to device with no upload endpoint and no intermediary host.
Chunked by default
Files are split into 32 KB chunks and reassembled on arrival, up to 100 MB by default. Chunk size and the maximum are set through FileTransferConfig.
Survives a dropped link
Each chunk is tracked and acknowledged on its own, so a link that drops mid-transfer redelivers only the chunks in flight, and a transfer follows DORS across a transport switch.
Progress and control
A file_progress event reports the percentage complete, getFileProgress reads status by id, cancelFileTransfer stops a transfer, and file_received fires on the recipient when the last chunk lands.
Encrypted like a message
Chunks travel with the protocol's default MLS end-to-end encryption, so a large payload is protected on the wire the same way a short message is.

Where it applies

Robotics and autonomy
Swarm coordination across fleets when links and GPS drop.
Public sector
Disaster-resilient communication through outages and shutdowns.
Industrial sites
Crews, equipment, and gateways keep coordinating off-grid, with the mesh moving with the work.
Above the transport
Service discovery turns the mesh into an invocable network of capabilities.

Mesh networking FAQ

Does mesh networking work without internet?

Yes. Devices connect directly over BLE and WiFi Direct and relay traffic for each other, so messages route peer to peer with no internet, no cell tower, and no router. When internet is present, DORS simply treats it as one more transport alongside Reticulum and Nostr fallbacks.

Can phones form a Bluetooth mesh network?

Yes. Ordinary iOS and Android phones running the SDK discover each other over BLE and connect over BLE or WiFi Direct, forming a mesh that relays messages up to 8 hops with no extra hardware.

How far can a mesh message travel?

Up to 8 hops in DORS. With WiFi Direct links spanning up to a couple hundred meters each, a single route can cover a venue, a convoy, or a neighborhood without infrastructure.

Does mesh networking drain the battery?

Relay duty is distributed by charge level. BLE advertisement is low-power by design, and devices below an energy threshold stop relaying automatically.

Can relay nodes read the traffic they forward?

No. Relays forward MLS-encrypted ciphertext. Only session members hold keys, and keys never leave their devices.

What happens when the internet is available?

DORS uses it as one transport among several, picking the best path per message. Losing it triggers failover to local transports, not an outage.

Can devices out of radio range still reach each other?

Yes. When no mesh path exists, the hosted relay carries MLS-encrypted messages between devices over the internet, enabled per app in the developer portal. Hosted relay deliveries are metered, 10,000 a month on Free, 100,000 on Pro, and 1 million on Scale, then $0.50 per 1,000, and local mesh traffic never is.

How does the mesh form?

Each device evaluates discovered peers against a connection budget of about four peers and a live score built from signal strength, free slots, uptime, battery, stability, and load. Peers in the same local group connect as members; peers in different groups connect as bridges, which is how separate pockets of devices merge into one routable mesh. The budget is rescored and rebalanced roughly every 15 seconds.

How is delivery confirmed?

Every message carries a unique ID and an 8-hop TTL. Receivers acknowledge, senders retry on timeout, and duplicates are dropped by ID, so the application sees exactly one delivered or one failed outcome per message.

What transports does the mesh run over?

Five: Bluetooth LE for energy-efficient local mesh, WiFi Direct for high-throughput links on Android (between iPhones the same slot runs over the Network framework), the internet as a WebSocket backhaul, Reticulum for resilient long-range fallback over an external daemon, and Nostr for a fallback over WebSocket relays. DORS scores whichever are enabled and moves traffic to the best one per message.

How does DORS avoid flapping between transports?

Three safeguards. A 15-point hysteresis means a rival transport must score at least 15 points higher before a switch, a 20-second cooldown spaces switches out, and an 8-second stability window requires the current transport to settle first. It escalates BLE to WiFi under load and switches away on poor signal, around -85 dBm.

How does a message get delivered when the recipient is offline?

It is held in the persisted outbox for up to 7 days and retried with exponential backoff, 1 second doubling to a 5 minute cap, for up to 10 attempts. A message with no path at all is parked and probed on every carrier, then re-driven the moment the peer reappears. If the peer comes back within the window, the message is delivered and message_delivered fires.

What stops a message from circulating the mesh forever?

Every message carries an 8-hop time-to-live that is decremented at each relay, and every device deduplicates by message id, tracking 5,000 recent ids for 7 days across restarts, so a message is processed once and dropped when its TTL reaches zero.

How large can a file be?

Up to 100 MB by default, in 32 KB chunks. Both are configurable through FileTransferConfig. Each chunk is acknowledged on its own, so a dropped link costs only the chunks in flight.

Are transferred files encrypted?

Yes. File transfer rides the same machinery as messages, including MLS encryption, DORS transport switching, and the acknowledgment and retry layer.

From the blog
How DORS failover works

Scoring five transports and moving traffic between them automatically.

Read more →
Store, carry, forward

Delay-tolerant delivery: custody transfer, message IDs and TTLs, deduplication, and reconcile-on-return.

Read more →

Run the mesh against your use case. Evaluations scope in 4 to 16 weeks.