Link Budget¶
TRANSMIT POWER · PATH LOSS · SENSITIVITY · MARGIN
A link works when more signal arrives at the receiving end than the chip needs. Everything in between is adding and subtracting decibels. This chapter sets up that sum, with firmware values where they exist and with explicitly marked assumptions where they do not.
[!NOTE] Source. This page has been verified against the firmware itself:
MeshCorev1.16.0, commit03b6ef4, 28 July 2026 — the rootplatformio.ini,src/helpers/radiolib/RadioLibWrappers.cppand theLORA_TX_POWERflags invariants/. Every figure on this page is recomputed bytools/link-budget.py.
[!WARNING] Two input values do not come from the firmware repo and are marked below with
°: the noise figure of the receive chain and the required SNR per spreading factor. They are constants at the top oftools/link-budget.pyand have not been verified against a datasheet. Every figure that follows from them carries the same uncertainty.
What the firmware fixes¶
Three values live in the root platformio.ini and apply to every board that
does not override them:
| Flag | Value |
|---|---|
LORA_FREQ |
869.618 MHz |
LORA_BW |
62.5 kHz |
LORA_SF |
8 |
[!NOTE]
LORA_SF=8is the compile-time default fromplatformio.ini, not the setting the Dutch network runs on. The radio parameters are overridden by the node configuration after flashing; the Netherlands preset sets SF7 with CR5 — see Getting Started. The sum further down this page uses the firmware default SF8 (−130.0 dBm). At SF7 the sensitivity is −127.5 dBm and the budget comes out 2.5 dB lower.
Transmit power is fixed per board. Counted across
variants/*/platformio.ini, active lines only:
LORA_TX_POWER |
Lines |
|---|---|
| 22 dBm | 93 |
| 20 dBm | 13 |
| 19 dBm | 1 |
| 10 dBm | 1 |
| 9 dBm | 4 |
| 8 dBm | 1 |
| 7 dBm | 2 |
That is 115 active lines across 76 variant directories. More lines than
directories, because a variant file can hold several [env:…] sections that
each set their own flag. The low values are not frugal boards but boards
with an external power amplifier: 7 dBm at the chip becomes well over 27 dBm
at the connector. See Antenna.
The noise floor¶
At the bottom of the sum sits the noise level. Thermal noise is −174 dBm per hertz at room temperature; over 62.5 kHz that is −126.0 dBm. The noise figure of the receive chain is added to that:
| Item | Value |
|---|---|
| thermal noise over 62.5 kHz | −126.0 dBm |
noise figure receive chain ° |
6.0 dB |
| receiver noise floor | −120.0 dBm |
[!NOTE] That the computed floor lands exactly on the −120 dBm at which the firmware clamps its own measurement is a coincidence with this noise figure, not a proof. The noise figure is an assumption; change it to 5 or 7 dB and the equality is gone. The clamp itself is in the firmware — see The LoRa Transceiver.
Sensitivity per spreading factor¶
LoRa receives below the noise floor. How far below depends on the spreading factor:
| SF | Required SNR ° |
Sensitivity |
|---|---|---|
| 7 | −7.5 dB | −127.5 dBm |
| 8 | −10.0 dB | −130.0 dBm |
| 9 | −12.5 dB | −132.5 dBm |
| 10 | −15.0 dB | −135.0 dBm |
| 11 | −17.5 dB | −137.5 dBm |
| 12 | −20.0 dB | −140.0 dBm |
Each SF step buys 2.5 dB of sensitivity and doubles the airtime. The effect of that airtime on the duty cycle is discussed in Regulations & Duty Cycle.
The sum¶
Take a node at 22 dBm, a half-wave dipole of 2.15 dBi on both ends and 1 dB of cable loss:
transmit power chip +22.00 dBm
antenna gain TX +2.15 dBi
cable loss TX −1.00 dB
------------------------------------
e.i.r.p. +23.15 dBm
antenna gain RX +2.15 dBi
cable loss RX −1.00 dB
sensitivity at SF8 −130.00 dBm
------------------------------------
budget 154.30 dB
That budget may be spent on path loss. In free space the path loss is 32.44 + 20·log(f in MHz) + 20·log(d in km):
| Distance | Free-space loss |
|---|---|
| 100 m | 71.2 dB |
| 1 km | 91.2 dB |
| 5 km | 105.2 dB |
| 10 km | 111.2 dB |
| 50 km | 125.2 dB |
A budget of 154 dB would reach more than a thousand kilometres in free space. That number is correct and useless at the same time: free space does not exist at ground level. The earth curves away, buildings and trees get in the way, and the Fresnel zone touches the ground long before the budget runs out. Free-space loss is an upper bound, not a prediction. Why practice falls so far short is in Higher and stronger isn't always better.
What a dB is worth¶
More useful than an absolute distance is the ratio. Every 6 dB doubles the distance in free space, every 6 dB less halves it:
| Change | Factor on distance |
|---|---|
| −6 dB | × 0.50 |
| −3 dB | × 0.71 |
| −1 dB | × 0.89 |
| +1 dB | × 1.12 |
| +3 dB | × 1.41 |
| +6 dB | × 2.00 |
That is where the practical value of this whole chapter sits. A bad connector with 3 dB of loss reduces your range by almost 30 percent. One SF step buys 2.5 dB and therefore a good 30 percent — but doubles the airtime. And an antenna one metre higher often beats both, because it removes the obstacle instead of trying to transmit through it.
Sources¶
Firmware, commit 03b6ef4 (v1.16.0, 28 July 2026):
platformio.ini—LORA_FREQ,LORA_BWandLORA_SFsrc/helpers/radiolib/RadioLibWrappers.cpp— the measured noise floor and the −120 dBm lower boundvariants/heltec_v3/platformio.ini—LORA_TX_POWER=22
In this repository:
tools/link-budget.py— recomputes every figure on this page
Not from the firmware repo: the noise figure of the receive chain and the
required SNR per spreading factor, both marked with °. The thermal noise
floor of −174 dBm/Hz is not a datasheet value but follows from kT at room
temperature.
Related in this documentation:
- The LoRa Transceiver — where the transmit power is set
- Antenna — gain and loss at the RF port
- Higher and stronger isn't always better — why free space is not practice
- Regulations & Duty Cycle — how much of this budget you may actually use
Translated from Dutch by Anthropic Claude