Offline file transfer over the mesh

Offline file transfer moves a photo, a document, or a batch of sensor payloads device to device across the mesh, with no server in the path. Files are chunked and move over the reliability layer, so a large payload survives a dropped link: only the missing chunks are resent, not the whole file.

Why files are hard off-link

A short message either lands or it does not. A file is different: it is large enough that the link will often drop before the last byte arrives. On a shared cloud, that is invisible because a resumable upload sits behind a stable connection to a server. In a blackout, a disaster zone, or a dead zone, there is no server and no stable connection, so a naive transfer that has to start over on every hiccup rarely finishes at all.

The fix is to treat the file the way the mesh already treats messages: split it into small pieces, track each one, and let the reliability layer carry only what is missing. That is what file transfer in the SDK does, and it rides the same DORS mesh the rest of the protocol runs on.

Sending a file

One call queues the transfer and returns a file id. Listen for file_progress to show a live indicator, and read status by id or cancel at any time.

TypeScript
// Send a file device to device, no server in the path
const fileId = await protocol.sendFile({
  recipient: 'user456',
  fileData: base64, // file contents as a base64 string
  fileName: 'document.pdf',
});

// Live progress as chunks move
protocol.on('file_progress', (event) =>
  console.log(`${event.percentage}% complete`));

// Check status, or stop a transfer in flight
const progress = await protocol.getFileProgress(fileId);
await protocol.cancelFileTransfer(fileId);

The recipient sees a file_received event on completion, carrying the file id, file name, file size, and sender.

How Offline Protocol implements it

A transfer is a stream of tracked chunks, not a single blob, which is what makes it recoverable, controllable, and safe over an unreliable link.

One call to send

sendFile takes a file path, a recipient, and an optional file name, and returns a file id. The file moves device to device with no server in the path.

Chunked by default

Files are split into 32 KB chunks and reassembled on arrival. Files up to 100 MB by default, with both chunk size and maximum size set through FileTransferConfig.

Progress and control

A file_progress event reports the percentage complete, getFileProgress reads status by file id, and cancelFileTransfer stops a transfer in flight.

Survives a dropped link

A file rides the same acknowledgment and retry reliability layer as messages, so a link that drops mid-transfer redelivers only the chunks in flight, not the whole file.

Chunked transfer, tuned to your payloads

By default a file is split into 32 KB chunks and reassembled on the far side, and a single transfer can carry a file up to 100 MB. Both numbers are configurable through FileTransferConfig: raise the maximum size for larger documents, or adjust the chunk size to match the links you expect in the field.

Chunking is what makes the transfer resilient. Because each chunk is tracked and acknowledged on its own, a link that drops mid-transfer costs only the chunk in flight, not the whole file. When the link returns, the transfer continues and sends only the chunks that are still missing.

It rides the same machinery as messages

File transfer is not a separate stack bolted onto the SDK. Chunks travel the same layers your messages do, which is why a transfer survives a dropped link and keeps going when the peer comes back.

DORS transport switching

A transfer follows the link that is working. If BLE weakens or congests, DORS moves the chunks to WiFi Direct or the internet, and the transfer carries on across the switch.

MLS encryption

Chunks travel with the protocol's default end-to-end encryption, so a large payload is protected on the wire the same way a short message is.

TTL and mesh routing

Chunks ride the multi-hop mesh with a time to live, so a file can reach a recipient several hops away without either device ever touching a server.

Ack and retry reliability

The same acknowledgment and retry layer that confirms messages tracks each chunk, so a transfer survives a dropped link and keeps going when the peer reappears.

Where it applies

Out of a blackout
Relaying a photo or update when the network is down and no server sits between the endpoints.
Through a disaster zone
Moving a signed document device to device across a broken area.
Off a device in a dead zone
Pulling sensor payloads out of a place with no coverage.
What it builds on
Runs over the DORS mesh, reports to the telemetry stream, and is one call in the same platform your app already runs.

Offline file transfer FAQ

How do you send a file with no server?

Call sendFile with a file path, a recipient, and an optional file name. The file is split into chunks and moved device to device across the mesh. There is no upload endpoint and no intermediary host; the bytes travel the same peer-to-peer paths your messages do.

How large can a file be?

Files up to 100 MB by default. Both the chunk size and the maximum file size are configurable through FileTransferConfig, so you can tune the transfer for your payloads and your links.

What happens if the link drops mid-transfer?

A file is a stream of chunks carried over the same acknowledgment and retry reliability layer as messages. A dropped link only costs the chunks in flight, and those are redelivered when the link returns, so the transfer continues rather than starting the whole file over.

Can I cancel or check on a transfer?

Yes. getFileProgress reads the current status by file id, cancelFileTransfer stops a transfer, and a file_progress event reports the percentage complete as chunks move.

Are transferred files encrypted?

File transfer rides the same machinery as messages, including MLS encryption. The chunks travel over the mesh with the protocol's default end-to-end encryption rather than a separate, weaker path.

How do I know when a file has fully arrived?

A file_received event fires on the recipient when the transfer completes, carrying the file id, file name, file size, and sender. Until then, file_progress reports the running percentage so you can show a live indicator.

What is the default chunk size?

Chunks are 32 KB by default. Chunking is what lets a large payload survive an unreliable link: each chunk is tracked and acknowledged on its own, so only what is missing has to be resent.

Move a file where there is no network. No server. Up to 100 MB.

Book a pilot Read the docs