Mesh Broadcast Algorithm
Current Algorithm
The routing protocol for Meshtastic is designed to support all kinds of different use-cases. Most importantly, it does not assume merely static nodes. If you want to test its theoretical performance, you can have a look at the simulator. The protocol is heavily influenced by the mesh routing algorithm used in RadioHead (which was used in very early versions of this project). It has four conceptual layers and (since version 2.6) uses a different approach for broadcasts and direct messages.
A Note About Protocol Buffers
Because we want our devices to work across various vendors and implementations, we use Protocol Buffers pervasively. For purposes of this document you mostly only need to consider the MeshPacket and Sub-packet message types.
Layer 0: LoRa Radio
All data is converted into LoRaLoRaA low-power, long-range wireless communication technology used by Meshtastic devices to enable communication over distances of several kilometers without the need for cellular, Wi-Fi, or other traditional network infrastructures. symbols which are sent to the radio for transmission. The details are described elsewhere, but it is worth noting that in addition to the converted packet bytes described below, there is also a preamble sent at the start of any data packet.
This preamble allows receiving radios to synchronize clocks and start framing. Below 1 GHz, Meshtastic uses a preamble length of 16, which is longer than the minimum preamble length of 8, to let SX126x LoRaLoRaA low-power, long-range wireless communication technology used by Meshtastic devices to enable communication over distances of several kilometers without the need for cellular, Wi-Fi, or other traditional network infrastructures. receivers sleep for a while, which lowers power consumption. Regions in the 2.4 GHz band use a preamble length of 12.
After the preamble comes the LoRaLoRaA low-power, long-range wireless communication technology used by Meshtastic devices to enable communication over distances of several kilometers without the need for cellular, Wi-Fi, or other traditional network infrastructures. Physical Header, which contains information about the packet length as well as a sync word to distinguish networks. For Meshtastic, it is set to 0x2B.
Layer 1: Unreliable Zero Hop Messaging
This layer is conventional non-reliable LoRaLoRaA low-power, long-range wireless communication technology used by Meshtastic devices to enable communication over distances of several kilometers without the need for cellular, Wi-Fi, or other traditional network infrastructures. packet transmission. A packet generated by a Meshtastic device has the following representation before encoding for transmission:
| Offset | Length | Type | Usage |
|---|---|---|---|
| 0x00 | 4 bytes | Integer | Packet Header: Destination. The destination's unique NodeID. 0xFFFFFFFF for broadcast. Little-endian. |
| 0x04 | 4 bytes | Integer | Packet Header: Sender. The sender's unique NodeID. Little-endian. |
| 0x08 | 4 bytes | Integer | Packet Header: The sending node's unique packet ID for this packet. Little-endian. |
| 0x0C | 1 byte | Bits | Packet Header: Flags. See the header flags for usage. |
| 0x0D | 1 byte | Bits | Packet Header: Channel hash. Used as hint for decryption for the receiver. |
| 0x0E | 1 byte | Bytes | Packet Header: Next-hop used for relaying. |
| 0x0F | 1 byte | Bytes | Packet Header: Relay node of the current transmission. |
| 0x10 | Max. 239 bytes | Bytes | Actual packet data: the encoded Data protobufProtobuf (Protocol Buffers). A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices., plus 12 bytes when PKCPKC (Public Key Cryptography). A cryptographic method introduced in Meshtastic v2.5 for Direct Messages and Admin Messages, where each device uses a unique public and private key pair. The public key, shared with other devices, enables secure message encryption, while the private key allows only the intended recipient to decrypt and authenticate the message. This approach enhances privacy and integrity for both direct device-to-device communication and sensitive admin functions. or AEAD encryption is used. Unused bytes are not transmitted. |
Packet Header Flags
| Index | # of Bits | Usage |
|---|---|---|
| 0 | 3 | HopLimit (see note in Layer 3) |
| 3 | 1 | WantAck |
| 4 | 1 | ViaMQTT (packet came via MQTTMQTT (Message Queuing Telemetry Transport). A lightweight messaging protocol designed for small sensors and mobile devices, enabling efficient data transmission in the Meshtastic network for Internet connectivity and integration with IoT platforms. See https://en.wikipedia.org/wiki/MQTT. In Meshtastic, MQTT is used to connect a node to the internet, and can be used to connect multiple meshes to each other.) |
| 5 | 3 | HopStart (original HopLimit) |
Usage Details
-
Packet Header: is described directly by the
PacketHeaderclass in the C++ source code. But indirectly it matches the first portion of theMeshPacketprotobufProtobuf (Protocol Buffers). A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices. definition. Note that the packet header is not encoded using a protobufProtobuf (Protocol Buffers). A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices., but is sent as raw bytes. This both saves airtime and allows receiving radio hardware to optionally filter packets before waking the main CPU. -
Packet Header - NodeIDs: A node's number is a CRC-32 of its public key. Before the node has a key, for example while its region is unset, the number comes from its MAC address.
-
Packet Header - Unique ID: The ID is a large, 32 bit ID to ensure there is enough unique state to protect an encrypted payload from attack.
-
Payload: An encrypted and packed protobufProtobuf (Protocol Buffers). A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices. encoding of the SubPacket protobufProtobuf (Protocol Buffers). A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.. Only the SubPacket is encrypted, while headers are not. This allows the option of eventually allowing nodes to route packets without knowing anything about the encrypted payload. For more information, see the encryption and Protobuf API Reference. A packet that would exceed the maximum length isn't sent.
Carrier-Sense Multiple Access with Collision Avoidance (CSMA/CA)
Meshtastic adopts CSMA/CA, similar to what is used in Wi-Fi. This means that all transmitters must perform Channel Activity Detection (CAD) before attempting to transmit. If the channel is considered busy, the node will wait until it is not anymore. Since once the channel becomes idle multiple nodes might want to start transmitting, a node has to wait a random multiple of slot times. The slot time is the time needed to reliably perform CAD. The number of slot times to wait is randomly picked from a contention window (CW), whose size depends on the current channel utilization. The contention window is larger for a higher channel utilization, to limit the chance of collisions.
Layer 2: Reliable Zero Hop Messaging
This layer adds reliable messaging between the node and its immediate neighbors only.
The default messaging provided by Layer 1 is extended by setting the WantAck flag in the MeshPacket protobufProtobuf (Protocol Buffers). A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.. If WantAck is set, the following documentation from mesh.proto applies:
This packet is being sent as a reliable message, we would prefer it to arrive at the destination. We would like to receive an ACK packet in response.
Broadcast messages treat this flag specially: Since ACKs for broadcasts would rapidly flood the channel, the normal ACK behavior is suppressed. Instead, the original sender listens to see if at least one node is rebroadcasting this packet (because naive flooding algorithm). If it hears that, the odds (given typical LoRaLoRaA low-power, long-range wireless communication technology used by Meshtastic devices to enable communication over distances of several kilometers without the need for cellular, Wi-Fi, or other traditional network infrastructures. topology) are very high that every node should eventually receive the message. So FloodingRouter.cpp generates an implicit ACK which is delivered to the original sender. If after some time we don't hear anyone rebroadcast our packet, we will timeout and re-transmit, using the regular resend logic.
If a transmitting node does not receive an ACK (or NAK) packet after a certain expiration time, it will use Layer 1 to attempt a re-transmission of the sent packet. A reliable broadcast is sent a maximum of three times in total, counting the first transmission, and a reliable direct message a maximum of five. If no ACK or NAK has been received by then the local node will internally generate a NAK (either for local consumption or use by higher layers of the protocol). The re-transmission expiration time is based on the maximum time it would take to receive an (implicit) ACK, taking into account the airtime of the sent packet, the current channel utilization, and a processing delay. For direct messages, the intended recipient will also send a real ACK all the way back to the original sender, but the device will only retransmit when it received no ACK at all.
Layer 3: Multi-Hop Messaging
Broadcasts using Managed Flooding
Given the various use-cases and scenarios Meshtastic supports, most of our protocol is built around flooding, meaning that every node rebroadcasts a packet it receives, up till a certain hop limit. However, an important difference in Meshtastic is that before rebroadcasting, a node listens a short while to see if another node has already rebroadcasted the packet. If so, it will not rebroadcast. "Managed Flooding" is therefore a better term.
The principle is as follows. If any mesh node sees a packet with a HopLimit other than zero, it will decrement that HopLimit and attempt to rebroadcast on behalf of the original sending node. In order to promote letting nodes that are further away flood the message, such that the message eventually reaches farther, the contention window (see Layer 1) for a flooding message depends on the Signal-to-Noise RatioSNR (Signal-to-Noise Ratio). A measure used in communications to quantify the level of a desired signal to the level of background noise. In Meshtastic and other wireless systems, a higher SNR indicates a clearer signal that can enhance the reliability and quality of data transmission. (SNRSNR (Signal-to-Noise Ratio). A measure used in communications to quantify the level of a desired signal to the level of background noise. In Meshtastic and other wireless systems, a higher SNR indicates a clearer signal that can enhance the reliability and quality of data transmission.) of the received packet. The CW size is small for a low SNRSNR (Signal-to-Noise Ratio). A measure used in communications to quantify the level of a desired signal to the level of background noise. In Meshtastic and other wireless systems, a higher SNR indicates a clearer signal that can enhance the reliability and quality of data transmission., such that nodes that are further away are more likely to flood first and closer nodes that hear this will refrain from flooding. The exception is the ROUTER and ROUTER_LATE roles, which rebroadcast even if they hear another node rebroadcasting. CLIENT_BASE does the same for packets to or from its favorited nodes.
Example
Below you see an example topology consisting of four nodes in CLIENT mode, where at a certain point node 0 wants to send a broadcast message.
Due to limited coverage, it only reaches nodes 1 and 2. Since node 2 is farther away, its SNRSNR (Signal-to-Noise Ratio). A measure used in communications to quantify the level of a desired signal to the level of background noise. In Meshtastic and other wireless systems, a higher SNR indicates a clearer signal that can enhance the reliability and quality of data transmission. is lower and therefore starts rebroadcasting earlier than 1.
After node 0 received this rebroadcast, its message is acknowledged. Note that a message is already acknowledged once a rebroadcast from any Meshtastic node (whether or not it has the same encryption key) is received.
Since node 1 heard the rebroadcast by 2, it will not rebroadcast again. Node 3 heard the message for the first time and the HopLimit is not yet zero, so it starts a rebroadcast for potential other receivers.

Direct messages using Next-Hop routing
Since version 2.6, Meshtastic uses a different approach for direct messages. Initially, the managed flooding approach as mentioned before is used to reach the destination. We'll then keep track of the node(s) that are trying to relay the packet for us. If upon a successful delivery, a response comes back (e.g., a NodeInfo response, acknowledgment or traceroute) and the node that relays this towards you was also (one of) the node(s) that relayed the original packet, it will be denoted as next-hop from now on. This means that instead of letting all nodes try to relay the packet, only the node for which the next-hop byte matches will. Note that this is determined per hop, so if there is an asymmetric link or a node on older firmware in between, managed flooding will be used on this hop. When a node moves, or RFRF (Radio Frequency). The radio signal a node transmits and receives over LoRa. conditions change, it might be the next-hop is not valid anymore. Therefore, a node will always fall back to managed flooding at the last retransmission attempt if it doesn't hear its next-hop relay. The procedure is visualized in the following diagram:

Regular broadcast intervals
Without additional configuration, a node broadcasts only its NodeInfo, every 3 hours by default (device.node_info_broadcast_secs).
Device telemetry and position are off by default:
- Device telemetry
- Turned on with
telemetry.device_telemetry_enabled - Interval set by
telemetry.device_update_interval - Default: 1 hour, or 12 hours for
ROUTERandROUTER_LATE
- Turned on with
- Position
- Shared only on channels where position precision is above 0
- Interval set by
position.position_broadcast_secs - Default: 1 hour, or 12 hours for
ROUTERandROUTER_LATE, with smart broadcast sending sooner after the node moves
As meshes grow larger and traffic becomes more contentious, the firmware will increase these intervals. This is in addition to duty cycle, channel, and air-time utilization throttling.
For meshes larger than 40 nodes (nodes seen in the past 2 hours), the firmware scales back position and telemetry intervals using the following algorithm:
ScaledInterval = Interval * (1.0 + (NumberOfOnlineNodes - 40) * 2^SF / (BW_kHz * 100))
SF and BW_kHz are the spreading factor and bandwidth in use. On Long Fast (SF11, 250 kHz), each node over 40 adds 0.08192. For example, a mesh of 62 online nodes on Long Fast stretches a 1-hour interval to about 168 minutes. Nodes in the ROUTER, ROUTER_LATE, SENSOR, TRACKER, and TAK_TRACKER roles aren't scaled.