Le-Space

under evaluation

LoRa Mesh

We set out with an idea: web apps that keep their data on the devices themselves (local-first) and keep running over a LoRa® radio mesh when the internet or the power grid fails, and in places that have neither. The measurements did not bury that idea; they cut it to size. The radio cannot carry the volumes of data people move every day. It does carry handshakes, bookings and signed events reliably across kilometres, with no infrastructure anyone has to operate. What the evaluation produced is a class of applications: mesh-calendar, an experimental appointment manager for hairdressers, already runs inside that byte budget.

funkpost on GitHub →

Findings

  • 29 September 2026 the change travels, not the entry. For one ticked box it is now the change itself that goes on the air, not the whole database entry that carried it.

    • 86 bytesagainst 1774
    • 10 secondsagainst three and a half minutes
  • 21 September 2026 a list that outlives the phone. A phone that had been reset got its list back with nothing in hand but the security key.

  • 19 September 2026 an identity that outlives the phone. Two phones that had never exchanged anything carry the same identity, derived from a security key rather than stored anywhere.

  • 18–19 September 2026 internet first, and the mesh when it goes. When the connection goes, only what changed since has to cross the radio.

    • 145 bytesone frame for the pointer
    • 7 frameswhat first contact costs otherwise
  • 6 September 2026 a booking crossed the mesh. A customer’s booking stood in the shop’s own day plan, with no IP path anywhere.

    • 31 secondsuntil the booking stood
    • 9.3 secondsof airtime, 2.5 % of the hour
  • 6 September 2026 the mesh carries the data, not the program. Shipping the app itself over the radio would take hours, so it arrives once by another route and is installed from then on.

    • 150 KBthe app, compressed
    • 780 framesthat over LoRa
  • 4 September 2026 first run over a real mesh. A todo list replicates between two browsers over a real mesh, and even three entries are noticeably sluggish.

    • ~6 minutesof airtime an hour, EU 868
  • Platform. Web Bluetooth runs only in Chromium on Android and desktop, in no iOS browser.

  • Adoption. Hardly anyone carries a radio node today, and that is less a verdict than the actual design problem.

The three planes

Three planes share the one radio and nothing else, and each is named for what crosses it: a handshake, the short exchange two devices use to agree a connection, a database, an event. Two have run over real hardware and carry what that cost; the third is drawn and not built:

The scheduling example exists now: mesh-calendar, a hairdresser’s appointment book running in the browser, where two tabs stand in for the radio when none is connected. Positioned not as a fallback for internet outages but as an alternative path: appointments synchronised into existing scheduling tools while generating no metadata in the first place.

The cut of the data decides what radios at all. The salon never sends a schedule: it sends the rules plus a busy mask: one bit per slot, three weeks in about 112 bytes, one frame, however full the calendar is. Free slots are computed locally, so browsing costs no airtime.

Yjs carries the rules; the log carries the bookings. The rules are written by a handful of stable devices, where merging genuinely helps. The bookings sit beside them in a log of signed, immutable records. Because a Yjs document greets its peers with a summary that grows with every author who has ever written: about six kilobytes, thirty frames, after a thousand customers, and it never shrinks. The log’s greeting is one small fingerprint per day, the same size at any scale, and it forgets last month instead of remembering it for ever.

What stays off the air is just as deliberate. The cancellation token (it lives in the .ics link; only the derived public key enters the document), the .ics file itself, and the verdict on a contested slot, which every device computes identically on read. Convergence is not agreement, so agreement is calculated, not transmitted.

Authority is a signature, not a convention. A decision not signed by the salon’s key is discarded on read, and a cancellation must carry the booking’s own capability signature. And the sync goes quiet on agreement: peers whose days match exchange one frame and fall silent.

Sequence diagram of two structures on one courier. The shop rules live in Yjs: a state vector is exchanged and the rules plus a busy-mask bitmap come back in one frame. The bookings sit beside them in a log of signed records, with a greeting of its own: one fingerprint per day, 111 bytes for three weeks, whether two people or two thousand have booked. If every day matches, the exchange ends after one frame. Only a day that differs costs anything — its keys, and the records that are missing. Free slots are computed locally. A booking travels as a signed log record, a decision as a record signed with the salon key, and only in ask mode — auto-confirm radios nothing back, because nobody decides and every device computes the same verdict on read. The capability token, the .ics file and names never cross the mesh. Sequence diagram of two structures on one courier. The shop rules live in Yjs: a state vector is exchanged and the rules plus a busy-mask bitmap come back in one frame. The bookings sit beside them in a log of signed records, with a greeting of its own: one fingerprint per day, 111 bytes for three weeks, whether two people or two thousand have booked. If every day matches, the exchange ends after one frame. Only a day that differs costs anything — its keys, and the records that are missing. Free slots are computed locally. A booking travels as a signed log record, a decision as a record signed with the salon key, and only in ask mode — auto-confirm radios nothing back, because nobody decides and every device computes the same verdict on read. The capability token, the .ics file and names never cross the mesh.

Try a plane

Both run in the browser. With ?mesh=bc two tabs stand in for the two radios, so neither needs hardware to try. A Meshtastic® node over Web Bluetooth makes it real. The run sheet says what a session on real radios still has to show. They are demonstrators, not products; the menu page says what that means.

Technical foundations

  • funkpost — the byte courier itself: framing, ARQ and duty-cycle pacing over Meshtastic® radios — two data planes built (OrbitDB and Yjs), signalling plane designed; live demos.
  • webrtc-qr — the library: two devices connect by scanning a code — no signalling server.
  • qr01 — the tutorial chapter for this: a todo list moves from phone to phone by scanning a code — over a Wi-Fi hotspot, with no internet involved.

Test channel

Two radios only hear each other if they carry the same key. If they do not, nothing arrives and nothing says so, which looks exactly like an empty room. This is ours, published on purpose: a meeting place for anyone wanting to try the demonstrators with someone else. It is not a secret, and nothing in them was protected by the channel key in any case.

QR code that imports the le-space.de test channel into a Meshtastic device

le-space.de · EU_868 · LONG_FAST · ⌗3dd3

Both demonstrators print that fingerprint beside the channel selector. It is worth comparing across devices: a channel can carry a familiar name and a completely different key, and the name will not tell you.

Importing replaces the entire channel set: every other channel on the device is erased, including keys that exist nowhere else. Export what is on there first.

  • Role CLIENT_MUTE. A default node rebroadcasts everything it hears, and on a busy mesh that is most of its airtime, spent on strangers’ packets. Muted, it carries only its own.
  • Preset SHORT_FAST for heavy testing: 10,940 bit/s against LONG_FAST’s 1,070. The same frame costs a tenth of the air, and range is irrelevant across a desk. Not SHORT_TURBO: it needs 500 kHz of bandwidth, EU 868 is 250 kHz wide, and it has no usable slot there at all. The preset is deliberately not baked into the channel above: it is part of the air configuration, so everyone testing together has to switch at once or they stop hearing each other.

The band is shared and legally rationed: EU 868 gives each transmitter about six minutes of airtime per hour, and a community mesh may have a hundred neighbours in earshot. Etiquette at the bench has the rest, and channels explains how to make your own.

Related work

  • btcmesh — sends signed Bitcoin transactions over a Meshtastic mesh to a relay that broadcasts them — the same courier pattern, applied to money.
  • darkwire — a Bitcoin 2025 hackathon project: an end-to-end Bitcoin transaction over LoRa, with no internet anywhere on the sender's side.
  • Reticulum — the scene’s cryptography-first mesh stack — runs over LoRa, packet radio, Wi-Fi and everything in between; internationally the best-known work of this kind.
  • MeshCore — a leaner LoRa mesh firmware currently building its own community in Germany alongside Meshtastic.
  • qaul — a messenger for internet shutdowns — devices connect directly over Bluetooth and Wi-Fi; well known in the net-freedom scene.

Communities within reach

  • Munich Mesh — the Munich Meshtastic community.
  • Berlin Chaos Mesh — Berlin’s mesh community around the c-base — Meshtastic, MeshCore and Reticulum.
  • MeshHessen — a regional mesh across the state of Hesse.
  • Meshtastic local groups — the directory of all local groups, from the D-A-CH Telegram to lora.ms.

Exchange

We share measurements and the test setup. Anyone working in the same niche is welcome to get in touch: Meshtastic practitioners, researchers, local-first developers.

Get in touch — contact@le-space.de Telegram · @lfp2p X · @nicokrausex

On the mesh, we can be reached at le-space.de e45c, YSGs0MrcH9QOcAlIxvYkJWaV64AvKgx/tXS27SiCzXM=

The public key is what identifies us; node names are assigned by whoever operates the node. It radios in the EU-868 region and is mobile, so it is reachable wherever it currently has a mesh in range.

Meshtastic Powered

LoRa® is a trademark of Semtech Corporation. Meshtastic® is a registered trademark of Meshtastic LLC. Meshtastic software components are released under various licenses, see GitHub for details. No warranty is provided - use at your own risk. This site is not affiliated with or endorsed by Semtech or the Meshtastic project.