Meshtastic up close: how a message hops through other people's nodes
Meshtastic is not a stack or a platform but a finished product: a cheap board with a LoRa radio, a phone over Bluetooth β and a chat that works where there is neither mobile coverage nor internet. This note is about how exactly a message hops through other people's nodes, how much airtime that costs and why a mesh chokes when there are too many nodes. The radio physics underneath is in the LoRa deep dive.
What it is β and what it is notβ
Meshtastic is firmware for cheap boards with a LoRa radio plus a phone app. A board for 20β40 dollars, flashed straight from the browser, a phone over Bluetooth β and you have a chat that does not know the word "provider".
The key difference from an ordinary walkie-talkie: a message does not have to reach the recipient directly. If somebody else with the same kind of node is between two people, it hops through them. Every participant is both a client and a relay at once β that is what turns a pile of separate radios into a network.
| what people usually expect | what it really is |
|---|---|
| "Internet without the internet" | A text chat, positions on a map and telemetry. No web, no mail, no files |
| "Works everywhere" | Works where radio reaches β your own or neighbouring nodes'. In an open field with no other nodes the range equals line of sight |
| "It is anonymous" | No. A node tells the air its own name, number and often its position |
| "The default channel is encrypted" | Formally yes, but its key is public and the same for everyone. It is "not plain text" rather than a secret |
| "The more nodes, the better" | Up to a point. Beyond it the network starts strangling itself β see "The air is finite" below |
| "You can make calls" | No. One packet is 237 bytes, the speed about a kilobit per second |
what it does well
Text and positions
Group messages in a channel, private ones to a single node, everyone's position on a map, battery and sensors. Exactly what you need on a hike, at a competition, on a building site or when the network is down.
what it does unexpectedly
Being eyes and hands
Sensors (temperature, pressure, water in the basement), buttons, sirens, home automation. A node without a phone is useful too: it can just report or relay.
what it fundamentally cannot do
Carry data
Photos, voice, files, streaming β no. This is not a question of firmware version: that much will not fit into air shared by everyone at once.
How it works in sixty secondsβ
The setup has four parts, and it is easy to mix up who does what.
A walkie-talkie hears only what reaches it directly. Meshtastic reuses other people's nodes: a message is retold by everyone who hears it for the first time. So in a city with a dozen active nodes there is a link where line of sight ended long ago.
The node: name, number, roleβ
The network has no registration and no accounts. A node simply switches on and starts telling the air about itself β and from those stories every neighbour builds its list of participants.
What a node says about itself
- NodeInfo β number, short and long name, board model, role
- Position β GPS coordinates, if enabled. Can be set by hand or not shared at all
- Telemetry β battery voltage and charge, channel utilisation, sensor data
- NeighborInfo β which nodes it hears directly: useful for the map, expensive for the air
The first thing to know
Right after flashing, remember: the short name, long name and position are visible to everyone in range, including strangers and people collecting nodes for public maps. If that was not the plan, turn position sharing off or set an approximate point by hand.
Channels and keys: who reads whatβ
This is where the most confusion and the most mistakes are: the word "encrypted" in Meshtastic means something quite different from what people usually imagine.
A channel is a "name + key" pair. Everything sent in the channel is encrypted with that key β AES, 128-bit for the default channel, 256-bit for one generated by the app. Whoever has the key reads everything. Channels are shared through a QR code or a link, and the key sits right inside it.
The catch is that the default channel, LongFast, has a public key that is the same for everyone on the planet. That is deliberate: so two strangers who switch on their boards for the first time hear each other straight away. But it means the default channel is a public square, not a private room.
1. The default channel is a public square, not a private room. 2. Whoever got the channel QR code reads everything in it for ever: the key does not expire and does not change by itself. 3. There is no forward secrecy here: if someone recorded the air and later got the key, old messages can be decrypted.
Packet anatomy: 16 + 237β
The radio frame here is limited to 256 bytes. Sixteen of them are header, the rest is payload. That number explains half of Meshtastic's limits.
The flags byteβ
Minus the header, minus the protocol's own fields β 237 bytes remain. The app will cut longer text or split it into several messages, and each one flies separately through the whole mesh. That is why long walls of text on air are bad manners: one such message can cost the network more than an hour of ordinary chat.
Managed flooding β the heart of the networkβ
Meshtastic has no routing tables and nobody who knows the network map. Instead there is a deliberately primitive rule: heard it for the first time β retell it once. All the engineering is in the word "managed": how to stop that rule turning the air into mush.
mechanism 1
The hop counter
The sender sets 3. Everyone who relays subtracts one; at zero the packet goes no further. The maximum is 7, but that is almost always a bad idea: every extra hop multiplies the number of transmissions on air.
mechanism 2
Recognising duplicates
Every packet has a number. A node remembers what it has already seen and simply throws the second copy away. Without this one message in a dense network would start an avalanche that jams the air for minutes.
mechanism 3
The farthest goes first
Before relaying, a node waits β the less time, the worse it heard the signal. So the farthest node relays first, the one that pushes the message furthest. The near ones, hearing the repeat, understand their help is no longer needed and stay quiet.
Pure flooding works well on dozens of nodes and poorly on hundreds. So in newer firmware a node remembers through whom it last reached a particular recipient and sends private messages along that path rather than to the whole network. Group messages in a channel still go by flooding β otherwise nobody would hear them.
Node roles β and why ROUTER is not a complimentβ
The role is a single setting that changes how a node behaves on air. And it is the most common way well-meaning beginners harm a network.
| role | what it does | who it suits |
|---|---|---|
| CLIENT | An ordinary participant: sends its own, shows the chat, relays others' | The default choice for 95 % of people. A board in a pocket, a car, on a desk at home |
| CLIENT_MUTE | The same, but does not relay others' | A dense city with dozens of nodes, where relaying adds nothing and only eats airtime and battery |
| ROUTER | Relays others' with priority, saves power, says less about itself | Only a node up high: a roof, a tower, a mountain. Not a flat |
| ROUTER_LATE | Always relays once, but after everyone else β to fill in coverage for its group of nodes | An extra node up high that backs up the main one rather than competing with it |
| TRACKER | Reports its position regularly, sleeps the rest of the time | A backpack, a bicycle, a dog, a drone |
| SENSOR | Reports sensor data on a schedule | A greenhouse, water level, a door sensor |
This list once also had a REPEATER role β a "mute" relay brick that does not show up in the node list. Since firmware 2.7.11 it is deprecated; masts now get ROUTER or ROUTER_LATE.
Setting the ROUTER role because it "sounds serious" and leaving the board on a windowsill. Such a node gets priority in relaying but hears badly β and instead of extending the network it only adds extra transmissions and talks over those who really are up high. The rule is simple: ROUTER is about height, not about wanting to help. If the node is not on a roof or a mountain, its role is CLIENT.
When CLIENT_MUTE makes sense
In the centre of a big city where thirty nodes are audible, one more relay statistically adds no coverage: everything it hears, its neighbours hear too. But it does add one more transmission to air that is already jammed. Turning relaying off in that situation is not selfishness but hygiene.
How many βroutersβ are really needed
A healthy mesh is a few nodes raised high and many ordinary clients. Not the other way round. One node on a hill gives more coverage than twenty on windowsills and at the same time reduces the load on the air, because a message needs fewer hops.
Radio presets: far versus fastβ
The radio settings here come down to one choice from a list β the preset. The most important thing about it: it is not a quality knob but a shared language. Nodes with different presets simply do not hear each other.
Besides the eight presets on the diagram there is also LONG_TURBO: SF11 on a 500 kHz band, 1.34 kbit/s. The wide band is not allowed in every region, so check your band's rules before using it. What lies behind SF and bandwidth is in the LoRa deep dive.
Going from LONG_FAST to LONG_SLOW adds a few decibels of sensitivity β and makes the network six times slower: 1.07 kbit/s versus 0.18. Raising the antenna by ten metres or fitting a proper antenna instead of the stubby one in the box gives many times more. Height and antenna almost always beat settings.
The air is finite: time on air and duty cycleβ
The most important section for anyone who wants their mesh to work. The whole network shares one frequency: while someone transmits, everyone else is silent. And transmission here is inconveniently slow.
The LONG_FAST preset gives about 1070 bits per second. A full packet is 253 bytes, that is over two thousand bits, so one long message occupies the shared air for over two seconds β with the preamble and LoRa's overhead symbols it comes to 2.1 s. And every node that relays it transmits it once more.
| what flies | size | airtime on LONG_FAST | how often |
|---|---|---|---|
| Node position | β 46 bytes | β 0.60 s | On a schedule, automatically β every node with GPS |
| Telemetry (battery, sensors) | β 40 bytes | β 0.56 s | On a schedule, automatically |
| NodeInfo (who I am) | β 60 bytes | β 0.68 s | Periodically, every node |
| Short message, 40 characters | β 56 bytes | β 0.68 s | When people write |
| Full message, 237 bytes | 253 bytes | β 2.12 s | When someone writes a wall of text |
Computed with the Semtech formula for LongFast: SF11, 250 kHz bandwidth, CR 4/5, a 16-symbol preamble β which is what Meshtastic uses. You can estimate your own case with the time-on-air calculator in the LoRa deep dive. And each of these numbers still has to be multiplied by the number of nodes that relay the packet.
channel utilisation Β· as the app shows it
What eats the most airtime
- β Short telemetry and position intervals β they multiply by the number of nodes
- β NeighborInfo: useful for the map, expensive for the air
- β Hop limit 7 instead of 3 β every extra hop multiplies transmissions
- β Long messages and bots that post to the channel regularly
- β An MQTT bridge set up so that it pulls the whole world into the local mesh
What makes the network better
- β Position and telemetry intervals in hours, not minutes
- β Hop limit 3, and in a small network even 2
- β One well-raised node instead of five on windowsills
- β CLIENT_MUTE where relaying adds nothing
- β Writing briefly: 40 characters take a third of the airtime of 237
In most regions these frequencies come with a duty-cycle limit: a device may transmit only a small share of the time. The firmware enforces it itself β and that is why it may quietly not send a message when the limit is used up. That is not a bug, it is the law.
Telemetry, positions, tracerouteβ
Most of the traffic in a typical mesh is not people chatting but nodes talking about themselves. It is worth knowing what exactly flies and why.
position
Where the node is
Coordinates from GPS or set by hand. The app's map shows everyone who shares a position. You can share nothing, an approximate position, or only within your own channel.
telemetry
How it is doing
Battery voltage and charge, channel utilisation, uptime. Plus sensor data if sensors are attached: temperature, humidity, pressure, water level.
traceroute
Which way it went
A separate button in the app: it shows the chain of nodes to the recipient and the signal quality on each leg. The most useful tool when working out why the link is bad.
MQTT: when the mesh climbs onto the internetβ
A node with Wi-Fi can become a bridge: everything it hears on air it forwards to a server on the internet β and back. This is Meshtastic's most controversial feature, because it is both the most useful and the most harmful.
Why people turn it on
- β To see their mesh on a public node map
- β To link two distant meshes β their own and friends' in another city
- β To pull telemetry into home automation or charts
- β To archive messages, because the node itself keeps nothing for long
Why people argue about it
- β A mesh that depends on the internet stops being a network "for when there is no internet"
- β A carelessly enabled downlink kills the local air with outside traffic
- β Everything sent to a public server on the default channel becomes public β positions included
The compromise: send, but do not receive β and not on the default channel.
Hardware: boards, antenna, solarβ
There is no "right" board β there are a few families, each for its own scenario. The difference between them is not speed but how long a node lives away from a socket.
A standalone node on a mastβ
The most useful thing you can do for a local network is to raise one node high and leave it there for good. It looks roughly like this:
What Meshtastic does not doβ
An honest list, so there are no disappointments. Almost everything here is not a missing feature but a direct consequence of the network being free, infrastructure-less and sharing one narrow frequency.
- β Does not anonymise. A node tells the air its name and number, often its position too. Anyone nearby sees who it is and where.
- β Does not hide by default. The default channel's key is the same for everyone on the planet. Privacy starts only with your own channel or with private messages.
- β Does not wait for the recipient. If a node is off right now, a message for it simply does not arrive. There is a separate Store & Forward module that stores and repeats messages, but it is a feature of a particular node, not of the network.
- β Does not guarantee delivery in a channel. Private messages are acknowledged; group ones fly "as they will".
- β Does not scale without limit. A few dozen active nodes in range β fine. A few hundred β the air runs out, and the network works worse precisely because there are more participants.
- β Does not carry data. No files, no photos, no voice: 237 bytes per packet and a kilobit per second is the ceiling.
And one more thing: the network does not work if the neighbours are set up differently. Region, preset and channel must match β the most common reason for "I see nothing".
Meshtastic and Reticulum: one board, different ideasβ
Their hardware is so alike that one board can run one and then the other. But they are tools for different jobs, and confusing them is very common.
| question | Meshtastic | Reticulum |
|---|---|---|
| What it is | A finished product: chat, map, telemetry. Switch it on β it works | A network stack: a construction kit on which people write their own applications |
| Carrier | LoRa only | LoRa, amateur radio, cable, TCP, I2P β anything |
| Address | 4 bytes from the board's MAC address | A 16-byte hash of a cryptographic key |
| Routing | Managed flooding, ceiling of 3β7 hops | Path tables, up to 128 hops, stitching different carriers together |
| Encryption | Channel key for groups; per-node keys for private messages | Always end-to-end, there is no off switch; ephemeral keys in sessions |
| Offline delivery | Only through a separate module on a particular node | Built in: delivery nodes hold the mail |
| Barrier to entry | An hour β and you are chatting | An evening β and you understand how it is built |
| Who it suits | A group in the mountains, volunteers, neighbours in a district, competitions | Those building their own network or an application for it |
Meshtastic answers the question "how do we talk without a network right now". Reticulum answers "how do we build a network nobody owns". The first is about this weekend's hike, the second about infrastructure.
Practice: from the box to a chatβ
The longest part is waiting for the parcel. The rest takes about an hour.
Three steps
Step 1 β a board for your region. The frequency depends on the country, and boards are sold for specific bands. Buying the "wrong" board is the most expensive mistake at the start: a different frequency means different radio hardware, and settings will not fix it. Ukraine uses the 433 and 868 MHz bands, and the firmware has separate regions for them β UA_433 and UA_868.
Step 2 β flashing straight from the browser. The official web flasher runs in Chrome or Edge: connect the board by cable, pick the model, one button. Nothing to install.
Step 3 β the app and first setup. The app connects to the node over Bluetooth. The region comes first: until it is set, the node does not transmit at all, and that is intended behaviour, not a fault. Then a name, the CLIENT role and sensible telemetry intervals.
The same from the command line
# node management utility
pip install meshtastic
# which node this is and how it is configured
meshtastic --info
# region β first and most important
meshtastic --set lora.region UA_868
# preset: change only together with everyone else
meshtastic --set lora.modem_preset LONG_FAST
# node names
meshtastic --set-owner "Petro's node" \
--set-owner-short "PTRO"
# report about yourself less often β saves airtime
meshtastic --set telemetry.device_update_interval 3600
meshtastic --set position.position_broadcast_secs 3600
# join a channel from a link
meshtastic --seturl "https://meshtastic.org/e/#..."
# post to the channel and list the nodes
meshtastic --sendtext "hello"
meshtastic --nodes
# which way packets go to a neighbour
meshtastic --traceroute '!8ab21044'
1. Switching the board on without an antenna attached β you can damage the radio. 2. Setting the ROUTER role in a flat. 3. Raising the hop limit to 7 "so it surely gets through". 4. Leaving telemetry and position intervals at minutes β and single-handedly loading the air of a whole district.
Glossaryβ
- Node ID β the node number: four bytes from the board's MAC address, shown as
!127a3f19. - Short name β four characters that label the node on the map and in the list. The long name is for people.
- Channel β a name plus a key. Whoever has the key reads everything in the channel. Shared by QR code or link.
- LongFast β the default channel and preset. Its key is public β it is the common air, not a private room.
- Preset β a set of radio parameters. A shared language: nodes with different presets do not hear each other.
- Hop limit β how many times a packet may be relayed. 3 by default, 7 at most. Every extra hop multiplies traffic.
- SNR / RSSI β how well a neighbour is heard. The delay before relaying is computed from SNR.
- Airtime β how long a packet occupies the air. A full message on LongFast takes over two seconds.
- Duty cycle β the legal limit on the share of time spent transmitting. The firmware enforces it and may not send a message.
- Channel utilization β how busy the air is. The main health indicator of a mesh.
- Role β how a node behaves on air: CLIENT, CLIENT_MUTE, ROUTER, ROUTER_LATE, TRACKER, SENSOR and a few narrower ones.
- NodeInfo β a node's periodic report about itself: number, names, hardware, role.
- Traceroute β the chain of nodes to the recipient and the signal quality on each leg.
- MQTT gateway β a node with Wi-Fi that forwards traffic between the air and a server on the internet.
- Store & Forward β a module on a particular node that stores messages and repeats them for those who were offline.
- PKC β per-node keys (Curve25519, since version 2.5) for private messages: they encrypt between specific nodes and confirm the sender.
Parameter and region names are worth checking against the documentation for your firmware version: the project moves fast.
- LoRa up close β the physical layer: chirps, spreading factor, time on air, range
- Reticulum up close β a network stack where the address is a key and LoRa is just one of the carriers
- Four internets β Reticulum, I2P, Yggdrasil and Nostr side by side: who sits on which floor
