Role Configuration and Tuning
Deep-dive configuration of ROUTER, ROUTER_CLIENT, and REPEATER roles including hop limit tuning and fixed-position setup.
- ROUTER vs ROUTER_CLIENT vs REPEATER Role: Deep Dive
- Hop Limit Configuration for Repeaters
- Fixed Position for Repeater Nodes
ROUTER vs ROUTER_CLIENT vs REPEATER Role: Deep Dive
Meshtastic provides three infrastructure-oriented device roles for nodes that exist to extend network reach rather than serve end users. Choosing the wrong role wastes resources, creates unnecessary air-time, or silently breaks the capabilities operators expect. This page dissects each role at the firmware level so you can make an informed decision for every node you deploy.
The Three Infrastructure Roles at a Glance
| Capability | ROUTER | ROUTER_CLIENT | REPEATER |
|---|---|---|---|
| Rebroadcasts all received packets | Yes | Yes | Yes |
| Keeps radio on continuously | Yes | Yes | Yes |
| Can originate user messages (text, position) | No | Yes | No |
| Maintains a node database (neighbor list) | Yes | Yes | No |
| Appears as a named node in the node list | Yes | Yes | No (anonymous relay) |
| Sends periodic NodeInfo broadcasts | Yes | Yes | No |
| Relative RAM/CPU overhead | Medium | Medium | Low |
ROUTER Role
A ROUTER node is the canonical fixed-infrastructure role. When you set a node to ROUTER it immediately adjusts its behavior in the following ways:
- The radio stays on full-time - no sleep modes, no duty-cycle restrictions beyond regulatory limits.
- Every received packet that passes the duplicate-detection filter is rebroadcast, regardless of packet type (text messages, position updates, telemetry, node info, traceroutes, etc.).
- The device sends its own
NodeInfoadvertisement on the configured broadcast interval so other nodes know it exists and can display it on the map. - The ROUTER maintains a full node database - it tracks neighbours, can respond to traceroute packets with hop-by-hop path information, and participates in neighbour-info exchanges.
- The ROUTER does not originate user-level messages. You cannot send a text from a pure ROUTER node. The device has no "Send" capability in the app because the firmware intentionally omits that code path for this role.
Setting the ROUTER role via CLI
meshtastic --set device.role ROUTER
Verifying the role was applied
meshtastic --get device.role
ROUTER_CLIENT Role
ROUTER_CLIENT is a superset of ROUTER. It retains every relay behaviour of ROUTER (radio always on, rebroadcast all packets, full node database, NodeInfo broadcasts) while also enabling the node to originate messages as a first-class client:
- Text messages can be composed and sent from the device (via app, web UI, or serial CLI).
- Position data from the device's own GPS (or manually configured coordinates) is broadcast on the position update interval.
- The operator at the repeater site can use the node for voice-channel communication during events or emergency activations without compromising the relay function.
The trade-off is marginal: originating position and telemetry packets increases local air-time slightly. On a busy channel this adds a few percentage points of channel utilisation compared to a pure ROUTER.
Setting the ROUTER_CLIENT role via CLI
meshtastic --set device.role ROUTER_CLIENT
REPEATER Role
The REPEATER role is the most minimal relay option. It is designed for nodes that should retransmit packets but consume the absolute minimum resources and produce no additional air-time of their own:
- Received packets are rebroadcast after the standard forwarding delay - identical to ROUTER in this respect.
- The node does not maintain a node database. It does not track neighbours, does not respond to traceroute requests, and does not build a picture of the mesh topology.
- The node does not broadcast
NodeInfoadvertisements. It is effectively anonymous from the rest of the network's perspective. It will not appear in the node list of clients that have not heard it directly. - No originating of user messages - same restriction as ROUTER.
- Because there is no node database to maintain and no periodic announcements to schedule, the firmware's memory and CPU footprint is reduced, which matters on resource-constrained platforms like the ESP32 with limited RAM.
The anonymity of the REPEATER role is a deliberate design choice: pure relay nodes that cannot be addressed individually produce less management overhead on the mesh. However, this also means you lose visibility - you cannot ping a REPEATER by node ID, and it will not show signal-strength data for incoming packets in the way a ROUTER does.
Setting the REPEATER role via CLI
meshtastic --set device.role REPEATER
Hop Count Handling Across Roles
All three roles participate in hop-count decrement identically. When a packet arrives with a remaining hop count of N, the forwarding node decrements it to N-1 before rebroadcasting. If N is already 0, the packet is consumed locally but not forwarded. Neither role has a bypass for the hop counter - there is no "always forward regardless" mode.
The practical consequence is that placing a REPEATER mid-path does use a hop. Plan your
network so that the number of infrastructure hops between any two end clients does not exceed
your configured hop_limit minus 1.
Choosing the Right Role
Community fixed repeater on a hilltop or tower
Use ROUTER. The node should be visible to the community (appears in node list, responds to traceroutes), but it should not be generating traffic of its own. Operators can still access the serial console locally for configuration without enabling ROUTER_CLIENT.
meshtastic --set device.role ROUTER
Ham operator's home station that also relays
Use ROUTER_CLIENT. You want the relay capability of ROUTER but also need to participate in mesh conversations - sending emergency alerts, coordinating with your community, or running net check-ins from the same hardware.
meshtastic --set device.role ROUTER_CLIENT
Minimal-overhead anonymous relay
Use REPEATER. Ideal for a small ESP32-based node tucked into a building to bridge two otherwise disconnected areas, where you do not need topology visibility and want the lowest possible firmware overhead.
meshtastic --set device.role REPEATER
Power Consumption Comparison
All three roles keep the radio on continuously, so the dominant power draw is similar. The differences arise from background processing:
- REPEATER wins on idle CPU and RAM usage because it skips node database maintenance entirely. On an ESP32 running at 240 MHz this typically saves 20 - 40 kB of heap and eliminates periodic database serialisation. In heavily node-dense networks this can be the difference between stable operation and heap exhaustion.
- ROUTER and ROUTER_CLIENT use similar power. ROUTER_CLIENT adds negligible overhead unless GPS is active, in which case GPS module draw (typically 20 - 50 mA for an active patch antenna) dominates everything else.
- All three roles draw roughly 100 - 160 mA at 3.3 V during LoRa TX (actual value depends on TX power setting and frequency). Receive mode is typically 10 - 15 mA. Idle-radio sleep, which only CLIENT role devices use, is not applicable to any infrastructure role.
Quick CLI power-related settings for infrastructure nodes
# Disable Bluetooth to save ~5 mA continuously
meshtastic --set bluetooth.enabled false
# Disable the screen backlight if present (saves 20-80 mA when display is on)
meshtastic --set display.backlight_secs 0
# Set a lower TX power if nodes are nearby (reduces TX draw and channel utilisation)
meshtastic --set lora.tx_power 17
Hop Limit Configuration for Repeaters
The hop limit is one of the most important and most misunderstood parameters in a Meshtastic
mesh. Setting it correctly reduces unnecessary rebroadcasts, controls how far a message
propagates, and prevents broadcast storms that saturate the channel. This page explains exactly
what hop_limit does, when to change it, and the CLI commands to apply it.
What hop_limit Controls
Every Meshtastic packet carries a hop count field in its header. This field is
initialised to the hop_limit value configured on the originating node at the
time the packet is sent. Each relay node (ROUTER, ROUTER_CLIENT (deprecated; use ROUTER or REPEATER instead), or REPEATER) decrements this
field by 1 before rebroadcasting. When a node receives a packet with a hop count of 0 it
delivers the packet locally but does not forward it further.
The formula for maximum relay chain length is:
Maximum relaying nodes = hop_limit
Total nodes that hear the original packet = hop_limit + 1 (originator counts as hop 0)
With the default hop_limit = 3, a packet originating at node A can reach:
- All nodes within direct radio range of A (hop 0 -> 1)
- All nodes reachable via one relay (hop 1 -> 2)
- All nodes reachable via two relays (hop 2 -> 3)
- All nodes reachable via three relays (hop 3 -> consumed, not forwarded)
In practice the default of 3 covers most community-sized networks with reasonable relay density.
The Default: hop_limit = 3
The firmware default of 3 is a careful balance. It is high enough to traverse a typical multi-node mesh with a few infrastructure repeaters, and low enough that a single rogue or misconfigured node cannot cause runaway rebroadcasting. Leave it at 3 unless you have a specific and measured reason to change it.
When to Increase the Hop Limit
Large geographically spread networks
If your community network spans a large geographic area - for example a county-wide emergency communications mesh with repeaters spaced 20 - 30 km apart - a hop count of 3 may not be sufficient to bridge the entire path. In this case, increasing to 4 or 5 gives messages the relay budget to traverse more infrastructure nodes.
Before increasing, first verify the actual hop count needed by running a traceroute between the two furthest nodes:
meshtastic --traceroute '!abcd1234'
Count the intermediate hops in the output. Set hop_limit to at least that number plus
one for margin.
# Increase hop limit on the originating/infrastructure node
meshtastic --set lora.hop_limit 4
When to Decrease the Hop Limit
Small, dense urban networks
In a dense neighbourhood deployment where every node can hear at least 2 - 3 others directly, a hop limit of 3 generates significant redundant retransmissions. Consider reducing to 2 if traceroutes show no path requires more than 2 relays.
meshtastic --set lora.hop_limit 2
Local-only repeater that should not propagate far
If you deploy a repeater specifically to bridge two buildings on the same campus - not to
reach the wider regional mesh - you can reduce its effective forwarding range by setting
hop_limit = 2 on packets it originates (its own NodeInfo, position, telemetry). This does
not prevent it from forwarding transit packets that arrive with a remaining count of 3, but it
limits the blast radius of traffic the repeater itself generates.
For even stricter isolation, combine a low hop limit with the
lora.ignore_incoming filter to whitelist specific node IDs that this repeater will serve.
The Broadcast Storm Risk Above hop_limit = 5
Values above 5 are explicitly discouraged by the Meshtastic project and should never be deployed on production networks. Here is why:
- Each relay creates a geometric increase in rebroadcasts. With 10 nodes each hearing 3 others, a hop_limit of 7 can generate hundreds of retransmissions per original packet.
- LoRa is a half-duplex medium. Each retransmission blocks all other transmissions in range for the duration of the air-time. Long SF12 packets at 250 bps can occupy the channel for 2 - 3 seconds each. A broadcast storm at hop_limit = 7 can push channel utilisation to 100% and render the network completely unusable.
- There is no back-off mechanism in the standard Meshtastic forwarding algorithm analogous to Ethernet CSMA/CD. Nodes will continue retransmitting even into a fully saturated channel.
If you feel you need a hop limit above 5, the correct solution is to add more infrastructure repeaters to shorten the required path, not to increase the hop counter.
Configuring hop_limit via CLI
# Set hop limit to 3 (default - recommended for most networks)
meshtastic --set lora.hop_limit 3
# Set hop limit to 4 (for large spread-out networks after traceroute verification)
meshtastic --set lora.hop_limit 4
# Set hop limit to 2 (for small dense networks or local-only repeaters)
meshtastic --set lora.hop_limit 2
# Verify the applied value
meshtastic --get lora.hop_limit
hop_limit Is a Per-Node Origination Setting
An important subtlety: hop_limit controls the initial value placed in packets that
this node originates. It has no effect on packets that arrive from another node already
carrying a hop count - those are forwarded as received (after decrement). Therefore:
- Setting
hop_limit = 2on a relay node limits only that node's own originations. - A packet originating elsewhere with
hop_limit = 5will still traverse your relay with a remaining count of 4 after decrement - your local setting does not cap it. - To limit how far foreign traffic propagates through your infrastructure, you must coordinate
hop_limitsettings across all nodes in your deployment, or use channel-level policies.
Monitoring Channel Utilisation After Changes
After adjusting hop_limit, monitor channel utilisation via the Meshtastic app or web UI. The target is below 25% utilisation on busy channels, below 10% on quiet channels. If you see utilisation spike after a hop_limit increase, your network density may not support the change and you should revert.
# Read current channel utilisation from device (shows as a percentage in debug output)
meshtastic --info | grep -i "channel util"
Fixed Position for Repeater Nodes
A repeater node that knows its own location serves the community in two ways: it appears accurately on coverage maps, and it lets neighbouring nodes calibrate their own position estimates. Without a fixed position, a GPS-less repeater either appears at coordinate (0, 0) in the ocean or does not appear on the map at all. This page explains how to configure a precise static position, how to reduce position precision for privacy, and how to minimise the air-time cost of periodic position broadcasts.
Why a Fixed Position Matters for Infrastructure Nodes
- Coverage visibility - Community members and emergency coordinators use the network map to understand what areas are served. A repeater with an accurate position lets them trace coverage boundaries and identify gaps.
- Traceroute path correlation - When operators run traceroutes, hop positions appear on the map. A correctly placed repeater gives a geographically meaningful path diagram.
- SNR context - Signal-to-noise ratio reports are much more useful when the receiving node's coordinates are known, because operators can correlate signal strength with distance and terrain.
- No GPS module required - Many dedicated repeater platforms (e.g. RAK WisBlock with no GPS module, T-Beam with GPS disabled) can broadcast a fixed configured position without incurring GPS power draw.
Configuring a Static GPS Position Without a GPS Module
Method 1: Meshtastic CLI
The --setlat, --setlon, and --setalt flags write a fixed position directly to
the device's configuration storage. Once set, this position is broadcast as the node's location
even with no GPS hardware present.
# Set position for a repeater at the top of Mount Davidson, San Francisco
# Latitude: 37.7406, Longitude: -122.4538, Altitude: 282 metres
meshtastic --setlat 37.7406 --setlon -122.4538 --setalt 282
Determine the coordinates of your site using Google Maps, CalTopo, or any mapping tool that provides WGS84 decimal degrees (the standard Meshtastic expects). Right-click the exact antenna location on Google Maps to copy coordinates.
Method 2: Meshtastic Python API
from meshtastic.serial_interface import SerialInterface
import meshtastic.mesh_pb2 as mesh_pb2
iface = SerialInterface()
# Build a Position protobuf
pos = mesh_pb2.Position()
pos.latitude_i = int(37.7406 * 1e7) # stored as integer, scaled by 1e7
pos.longitude_i = int(-122.4538 * 1e7)
pos.altitude = 282
pos.time = 0 # will be filled in by firmware
iface.localNode.setPosition(pos.latitude_i / 1e7, pos.longitude_i / 1e7, pos.altitude)
iface.close()
Method 3: Meshtastic Web UI
Connect to the node's web interface (available on ESP32-based devices at
http://meshtastic.local or the device's IP when connected to Wi-Fi). Navigate to
Config → Position, enable Fixed Position, and enter latitude, longitude,
and altitude. Save and reboot.
Position Precision: Reducing Exact Location for Privacy
If the repeater is on private property and the owner does not want the exact address broadcast on the mesh, reduce position precision. Meshtastic supports precision levels from full resolution (sub-metre) down to approximately 23 km radius.
Common choices for community repeaters:
- Full precision (default) - broadcast exact coordinates. Acceptable for tower sites, mountain tops, and public-land installations.
- ~1 km precision - rounds to the nearest kilometre. Identifies the general neighbourhood without revealing the specific building.
- ~10 km precision - rounds to the nearest 10 km. Useful for regional-scale maps where sub-kilometre accuracy is unnecessary and the operator prioritises privacy.
# Set position precision to approximately 1 km (precision value 14)
meshtastic --set position.position_precision 14
# Set position precision to approximately 10 km (precision value 11)
meshtastic --set position.position_precision 11
# Restore full precision (precision value 32)
meshtastic --set position.position_precision 32
The position_precision value is a bit-field width - higher values mean more significant
bits retained from the raw coordinate, i.e. higher accuracy. Values below 10 round so
aggressively that the position becomes almost meaningless for map purposes.
Position Broadcast Interval for Fixed Nodes
A fixed repeater does not move. Broadcasting its position every few minutes - the default
behaviour when position_broadcast_smart_disabled is false - wastes significant air-time
that could be used by mobile nodes. For a static infrastructure node, set the broadcast
interval to at least 12 hours (43200 seconds), or even 24 hours (86400 seconds).
# Set position broadcast interval to 12 hours (43200 seconds)
meshtastic --set position.position_broadcast_secs 43200
# Set position broadcast interval to 24 hours (86400 seconds) - recommended for fixed sites
meshtastic --set position.position_broadcast_secs 86400
# Disable smart position updates (these are based on movement; irrelevant for fixed nodes)
meshtastic --set position.position_broadcast_smart_disabled true
With a 24-hour interval, a fixed repeater broadcasts its position exactly once per day on power-up plus once per day thereafter. Compare this to the default which can produce a position packet every 5 - 15 minutes - saving dozens of transmissions per day across a network with multiple infrastructure nodes.
Verifying the Fixed Position Was Applied
# Check position configuration on the device
meshtastic --get position
# Pull the device info including last known position
meshtastic --info | grep -A 5 position
After the node reboots following a position update, connect to the Meshtastic app and look at the node list. The repeater should appear at the correct location on the map within one position broadcast interval.
Altitude Accuracy
Altitude in Meshtastic is stored in whole metres above the WGS84 ellipsoid (not above sea level). For antenna-height accuracy, use the elevation of the antenna itself, not ground level at the base of the tower. For most community mapping purposes, ground-level elevation from a topo map is sufficient - the difference rarely affects coverage visualisations.
Find accurate elevation using the USGS National Map (apps.nationalmap.gov) or
open-elevation.com/api/v1/lookup?locations=LAT,LON for non-US sites.