LoRaWAN Adaptive Data Rate: Spreading Factors, Airtime, Duty Cycle and Network Capacity Planning (2026)

LoRaWAN Adaptive Data Rate: Spreading Factors, Airtime, Duty Cycle and Network Capacity Planning (2026)

LoRaWAN Adaptive Data Rate: Spreading Factors, Airtime, Duty Cycle and Capacity Planning

A LoRaWAN pilot with fifty sensors works beautifully. The same design with five thousand sensors quietly collapses: uplinks vanish, batteries die in months instead of years, and the network server shows devices stuck at the slowest data rate. Almost every one of those failures traces back to one mechanism, LoRaWAN adaptive data rate (ADR), and to the physics it manages: spreading factor, time on air, duty cycle and ALOHA collisions.

This matters in 2026 because deployments have moved from pilots to fleets. Utilities, cold chains and campus metering now run tens of thousands of nodes per network, and capacity is a design variable, not an afterthought. In this guide you will leave with the airtime formula and worked numbers, the ADR algorithm as it actually runs on a network server, an ALOHA capacity model you can reuse in a spreadsheet, a battery-life comparison, and a failure-mode checklist.

What this covers: the LoRa physical layer, time on air with worked numbers, regional rules, the ADR loop on device and server, capacity and gateway-density maths, Class A/B/C energy costs, ChirpStack configuration, and the failures that break real networks.

Context and Background

LoRa is a proprietary chirp spread spectrum (CSS) modulation from Semtech; LoRaWAN is the open MAC layer specified by the LoRa Alliance that sits on top of it. The physical layer trades data rate for sensitivity: each step up in spreading factor (SF) roughly doubles the symbol time and buys about 2.5 dB of receiver sensitivity. The MAC layer adds the rules of the road: device classes, join procedures, MAC commands, and the regional parameters that encode what each country’s regulator allows.

The incumbents for long-range, low-power sensing are LoRaWAN, NB-IoT and LTE-M on licensed spectrum, and newer entrants such as Wi-Fi HaLow. We compared those trade-offs in our Wi-Fi HaLow vs LoRaWAN vs LTE-M selection guide. LoRaWAN’s distinguishing property is that you own the infrastructure: gateways are cheap, there is no per-device subscription to a carrier, and the network server is software you can run yourself with ChirpStack or consume as a service such as The Things Stack. The price of that freedom is that capacity is your problem.

Unlicensed spectrum means shared spectrum. In Europe the 863 to 870 MHz band is governed by duty-cycle limits; in North America the 902 to 928 MHz band is governed by dwell-time and frequency-hopping rules. Neither guarantees you exclusive use of a channel, so a LoRaWAN network is fundamentally a random-access system. Devices transmit when they have data, with no carrier sensing and no scheduler. That is the ALOHA model, and it caps what a channel can carry no matter how clever the radio is.

ADR is the control loop that makes that random-access system efficient. Without it, every device would pick a conservative spreading factor, usually SF12, and the airtime would swamp the channel. With it, devices near gateways use SF7 and a handful of milliseconds on air, leaving the long, expensive transmissions to the few nodes that truly need them. The LoRa Alliance publishes the normative text in the LoRaWAN specification and the Regional Parameters documents (see the LoRa Alliance for current versions); The Things Network documents a practical implementation of its adaptive data rate behaviour, which is based on Semtech’s recommended algorithm.

A note on sourcing. Parameter tables below (data rates, sub-band duty cycles, default channels) were checked against The Things Network regional documentation. Chip-level figures such as sensitivity and current draw vary by silicon and are labelled as typical or illustrative; always confirm against your radio’s datasheet.

The LoRa Physical Layer and the ADR Control Loop

Direct answer: LoRaWAN ADR is a closed loop in which the network server measures the signal-to-noise ratio (SNR) of recent uplinks, compares it with the SNR the current spreading factor needs, and sends a LinkADRReq MAC command that lowers the spreading factor or transmit power when there is spare margin. The result is shorter airtime, lower energy use and more network capacity.

LoRaWAN adaptive data rate control loop between end device, gateway and network server

Figure 1: The ADR control loop. The device uplinks with the ADR bit set, gateways forward SNR metadata, the network server evaluates margin and answers with LinkADRReq inside a Class A receive window.

Figure 1 shows the loop end to end. The device sets the ADR flag in the frame control field of every uplink, which tells the network server that it is allowed to manage the device’s data rate and transmit power. Gateways forward each received frame together with RSSI and SNR metadata. The network server accumulates a history per device, decides whether the data rate is suboptimal, and piggybacks a LinkADRReq on the next downlink. The device applies the change and answers with LinkADRAns in its next uplink. The key point: the intelligence lives on the server, and the device only obeys, plus a safety net described below.

Chirp spread spectrum and what spreading factor means

A LoRa symbol is a chirp, a signal whose frequency sweeps across the whole channel bandwidth. Information is encoded in the starting offset of that sweep. With spreading factor SF, a symbol carries SF bits and lasts T_sym = 2^SF / BW seconds. At 125 kHz bandwidth that is 1.024 ms at SF7 and 32.768 ms at SF12, a 32-fold difference.

Higher SF means longer symbols, which concentrates more energy per bit and lets the receiver demodulate signals below the noise floor. Typical demodulation SNR limits are about -7.5 dB at SF7, -10 dB at SF8, -12.5 dB at SF9, -15 dB at SF10, -17.5 dB at SF11 and -20 dB at SF12 (Semtech figures widely reproduced in stack documentation; verify for your silicon). Each SF step therefore buys about 2.5 dB of link budget while costing roughly twice the airtime.

Spreading factors are quasi-orthogonal: two frames at different SFs on the same channel can usually be received simultaneously, though not perfectly, with cross-SF interference degrading both when the power imbalance is large. Frames at the same SF on the same channel collide destructively unless one is sufficiently stronger, which is the capture effect covered later.

Bandwidth, coding rate and the data-rate table

LoRaWAN fixes combinations of SF and bandwidth into numbered data rates (DR). For EU868, per the TTN regional documentation, DR0 to DR5 are SF12 to SF7 at 125 kHz, with nominal bit rates from 250 bit/s to 5,470 bit/s. DR6 is SF7 at 250 kHz (11 kbit/s) and DR7 is FSK at 50 kbit/s. In the US915 plan, DR0 to DR3 are SF10 to SF7 at 125 kHz, and DR4 is SF8 at 500 kHz for the wideband uplink channels; US915 never uses SF11 or SF12 for uplink, a consequence of its dwell-time limit.

Coding rate adds forward error correction: 4/5 to 4/8. LoRaWAN uses 4/5 by default, and the nominal bit rates quoted above assume it. Raising the coding rate lengthens the frame and rarely helps in practice; ADR does not manage it.

ADR is two knobs, not one

ADR manipulates data rate (spreading factor and, in some plans, bandwidth) and transmit power. The reference algorithm exhausts the data-rate knob first, lowering SF while margin lasts, and only then reduces transmit power in fixed steps. The reasoning is energy: shortening airtime by 2x saves far more battery than shaving 3 dB of power. For a typical sub-GHz radio the transmit current falls only modestly with output power, so airtime dominates the energy bill.

The device-side counterpart is the ADR backoff. A device that sets the ADR bit counts uplinks since its last downlink. After ADR_ACK_LIMIT uplinks (64 by default in the specification) it sets the ADRACKReq bit to solicit any downlink from the network. If no reply arrives within a further ADR_ACK_DELAY uplinks (32 by default), the device steps its data rate down, increasing SF to recover range, and keeps stepping down every ADR_ACK_DELAY uplinks until it reaches the minimum rate or hears the network again. This is the safety net that rescues a device that moved, lost a gateway, or lost a LinkADRReq in transit.

Time on Air: The Maths That Drives Everything

Airtime is the currency of a LoRaWAN network. Every capacity limit, duty-cycle limit and battery estimate is a function of it, so the formula is worth knowing cold. Semtech’s SX127x documentation gives it; the implementation is mechanical.

LoRa airtime versus spreading factor for a 23-byte frame and the 1 percent duty cycle minimum interval

Figure 2: Airtime and the resulting minimum transmit interval under a 1 percent duty cycle for a 23-byte PHY payload at 125 kHz. Each spreading factor step roughly doubles airtime.

The formula

The preamble lasts (n_preamble + 4.25) symbols, with n_preamble = 8 in LoRaWAN. The payload symbol count is:

n_payload = 8 + max( ceil( (8 PL – 4 SF + 28 + 16 CRC – 20 IH) / (4 (SF – 2 DE)) ) x (CR + 4), 0 )

where PL is the PHY payload length in bytes, CRC is 1 if the payload CRC is enabled (it is on uplinks, off on downlinks), IH is 1 for implicit header (LoRaWAN uses the explicit header, so 0), DE is 1 when low-data-rate optimisation is on (mandatory for SF11 and SF12 at 125 kHz), and CR is the coding-rate index (1 for 4/5). Total time on air is (n_preamble + 4.25 + n_payload) x T_sym.

Worked numbers

LoRaWAN adds 13 bytes of overhead to the application payload on a standard uplink: 1 byte MHDR, 4 bytes DevAddr, 1 byte FCtrl, 2 bytes FCnt, 1 byte FPort, and 4 bytes MIC. A 10-byte sensor reading becomes a 23-byte PHY payload. Applying the formula at 125 kHz, CR 4/5, with CRC on, I computed the following (these are calculated from the formula, not measured):

SF T_sym Payload symbols Airtime (23-byte PHY) Min interval at 1% duty cycle
SF7 1.02 ms 48 61.7 ms 6.2 s
SF8 2.05 ms 43 113.2 ms 11.3 s
SF9 4.10 ms 38 205.8 ms 20.6 s
SF10 8.19 ms 33 370.7 ms 37.1 s
SF11 16.38 ms 38 823.3 ms 82.3 s
SF12 32.77 ms 33 1,482.8 ms 148.3 s

Read the last column carefully. A 1% duty cycle means a device may transmit for at most 1% of the time within a sub-band, so after sending a frame that lasts t seconds it must stay quiet on that sub-band for 99t seconds, or about 100t between starts. At SF12 that is 148 seconds between uplinks; at SF7 it is 6. The 24-fold airtime ratio between SF7 and SF12 is the single most important number in this article.

Why the ratio is 24 and not 32

Symbol time grows 32-fold from SF7 to SF12, but the symbol count falls because each higher-SF symbol carries more bits, and low-data-rate optimisation reduces the effective bits per symbol further at SF11 and SF12. The net is roughly a 24-fold increase for this payload size. For tiny payloads the preamble dominates and the ratio approaches 32; for large payloads it drifts toward the pure bit-rate ratio (5,470 / 250, about 22).

Airtime is the cost; sensitivity is the benefit. Typical SX127x-class receiver sensitivity at 125 kHz is around -123 dBm at SF7 and -137 dBm at SF12 (Semtech datasheet typicals; treat as indicative). The 14 dB spread is the range you buy with 24 times the airtime. In a path-loss model with exponent n, 14 dB of link budget multiplies range by 10^(14 / (10 n)): about 2.5x for n = 3.5 and 3.2x for n = 2.8. In urban clutter, the same budget can vanish into a single wall.

With a 14 dBm EIRP transmitter, SF12 gives a maximum coupling loss near 151 dB before antenna gains, whereas SF7 gives about 137 dB. ADR’s job is to find, per device, the cheapest SF whose sensitivity still clears the actual path loss plus a safety margin.

Regional Rules: Duty Cycle, Dwell Time and Channel Plans

The same radio behaves differently in each region because the regulator, not the protocol, sets the transmit limits. ADR operates inside those limits, so you must plan against the region’s constraint rather than against LoRa in the abstract.

EU868: duty cycle by sub-band

European rules limit how much of the time a device may occupy each sub-band. The TTN regional documentation lists the sub-bands as follows: 863 to 865 MHz at 0.1%, 865 to 868 MHz at 1%, 868 to 868.6 MHz at 1%, 868.7 to 869.2 MHz at 0.1%, 869.4 to 869.65 MHz at 10% with up to 500 mW ERP, and 869.7 to 870 MHz at 1%. The three default join channels, 868.1, 868.3 and 868.5 MHz, all fall in the 868 to 868.6 MHz sub-band, so they share one 1% budget. Maximum EIRP is +16 dBm (+14 dBm ERP), and the default RX2 window is 869.525 MHz at DR0 (SF12), which sits in the 10% sub-band so that gateways can answer devices without exhausting the 1% budget.

The pivotal detail is that the duty cycle is a per-device obligation for uplinks but a per-gateway obligation for downlinks. Every end device must respect 1% on its own transmissions. The gateway must also respect 1% on the sub-band it uses for RX1 replies, which is the same sub-band as the uplink. A single SF12 downlink of an acknowledgement lasts well over a second; at a 1% limit the gateway then cannot use that sub-band for roughly 100 times as long. This is why downlinks, not uplinks, are the scarce resource in dense EU868 networks, a point we return to in the section on confirmed uplinks.

US915 and AU915: dwell time and sub-bands

In the United States the FCC rules for the 902 to 928 MHz band do not impose a duty cycle for frequency-hopping systems but do limit dwell time. The LoRaWAN US915 plan accordingly caps each transmission at 400 ms on a channel, which is why SF11 and SF12 at 125 kHz are not used for uplinks (they would exceed it for any realistic payload). US915 defines 64 uplink channels of 125 kHz and 8 uplink channels of 500 kHz, and most gateways listen to only one group of 8 plus its paired 500 kHz channel, often called a sub-band or FSB. Devices must be configured with a matching channel mask. A fleet left on the wrong sub-band is the classic reason that devices join and then go silent, and it is also why the first ADR request after a join in US915 and AU915 is typically a channel-mask message (TTN describes this initial request in its ADR documentation).

AS923 and IN865

AS923 serves much of Asia-Pacific with country-specific parameters, including per-country maximum EIRP and in some countries listen-before-talk or dwell-time requirements. IN865 is the India plan, covering 865 to 867 MHz. I have not verified current duty-cycle or EIRP parameters for these two plans against the latest Regional Parameters release, so treat the specifics as to-be-confirmed: consult the LoRa Alliance RP002 document and local regulation (in India, the Department of Telecommunications rules) before finalising a design. The structural lesson is the same everywhere: look up the regional constraint first, derive the minimum interval or maximum airtime from it, and only then size the network.

Regional comparison

Region Constraint style Practical effect on ADR
EU868 Duty cycle per sub-band (0.1 to 10%) Airtime budget caps message rate; low SF is a regulatory advantage
US915 400 ms dwell, hopping across channels SF11/SF12 unavailable on uplink; fewer SF levels for ADR to use
AU915 Similar structure to US915 Channel-mask management after join is important
AS923 Country-specific (verify) Check LBT and dwell rules per country
IN865 Verify with current RP002 and local rules Check before sizing

How the Network Server Actually Runs ADR

The specification defines the MAC commands and the device behaviour, but the server-side algorithm is deliberately left to implementers. Semtech published a recommended algorithm, and most stacks, including TTN, implement a variant of it. ChirpStack ships a default ADR engine and also supports custom ADR plugins written in JavaScript, according to its configuration documentation.

ADR decision flow on the network server using SNR margin and installation margin

Figure 3: ADR decision logic. The server takes the maximum SNR over a window of recent uplinks, subtracts the required SNR and an installation margin, then converts the remaining margin into steps.

The reference algorithm step by step

For each device, the server keeps a window of recent uplinks. TTN documents using the 20 most recent uplinks, each recorded with its frame counter, SNR and the number of receiving gateways. For every uplink it uses the best gateway’s SNR. The algorithm is:

  1. Take SNR_max, the highest SNR in the window (some implementations use the average, which is more conservative).
  2. Look up SNR_required for the device’s current data rate (for SF9 at 125 kHz, about -12.5 dB).
  3. Compute margin = SNR_max – SNR_required – installation_margin.
  4. Compute N_step = floor(margin / 3), since each SF step changes the required SNR by roughly 2.5 dB and the algorithm rounds up to 3 dB.
  5. While N_step is positive and a faster data rate exists, increase the data rate by one step and decrement N_step.
  6. When the data rate is at maximum and N_step is still positive, reduce transmit power by one 2 dB index per step.
  7. While N_step is negative and transmit power is below maximum, increase power.
  8. If the result differs from the device’s current settings, schedule a LinkADRReq.

The point in step 7 is subtle and often misunderstood: the reference algorithm does not slow the data rate when margin is negative. It only restores transmit power. Recovering from a deteriorated link by raising SF is left to the device-side backoff described earlier, which uses the ADRACKReq timer. A well-designed server implementation can add its own downward step, and TTN notes that it also sends a request when a device sits at DR0 with enough measurements to improve, but you should not assume symmetric behaviour across stacks.

A worked example

Take a meter currently at SF10 (required SNR about -15 dB) with an installation margin of 10 dB. Over its last 20 uplinks the best SNR seen is +2 dB. Margin = 2 – (-15) – 10 = 7 dB, so N_step = floor(7 / 3) = 2. The server steps from SF10 to SF9 then SF8 (two steps), and the next uplink arrives at SF8. Airtime for the 23-byte frame falls from about 371 ms to about 113 ms, a 3.3x reduction, so the meter’s transmit energy falls by the same factor. If the meter is later moved behind a concrete wall and its SNR drops by 8 dB, the server will not raise SF; the device will notice after 64 uplinks without any downlink, set ADRACKReq, and after 32 more begin stepping SF up on its own. Recovery is slow by design.

Installation margin is the main tuning knob

Installation margin, 10 dB in many reference configurations, is the headroom held back for fading, seasonal foliage, and antenna or enclosure variance. ChirpStack exposes it as installation_margin in its region network configuration, and its documentation notes that a higher value lowers data rates but reduces the chance a device is disconnected. Its sample configuration shows a value of 10 and also exposes min_dr, max_dr and adr_disabled; I could not confirm from the documentation which of these are shipped defaults, so check your version’s reference file.

Choosing the margin is a risk decision. Each extra 3 dB of margin costs one spreading factor, roughly doubling airtime for the devices affected. For a fleet of static indoor meters with stable propagation, 5 to 7 dB can be justified after field measurement. For outdoor devices exposed to weather, foliage or vehicle traffic, 10 dB or more is prudent. The cost of too little margin is not just lost packets but oscillation, covered in the failure-mode section.

What ADR needs in order to work

ADR assumes a stationary link. Measurements are averaged over many uplinks, adjustments take at least one downlink, and the server cannot see the true path loss, only the received SNR at the gateways that heard the frame. TTN’s guidance is explicit: enable ADR when RF conditions are stable, which generally means static devices; mobile devices should enable it only when they detect they have been stationary for a while, and the device, not the application, decides.

ADR also needs a downlink path. Each LinkADRReq consumes gateway downlink airtime, and in EU868 that airtime is the scarce resource. A server that sends ADR commands to thousands of devices at once, for instance after a reconfiguration, can saturate the downlink duty cycle of its gateways. Staggering the changes, and letting the server piggyback commands on application downlinks or acknowledgements, avoids the problem.

Mobile and intermittently moving devices

Asset trackers and vehicle sensors break ADR’s assumptions. Strategy options, in rough order of robustness, are: fix the data rate to a value that covers the worst case in the service area and disable ADR; use a mobility-aware device that switches ADR on only when an accelerometer reports it has been still for some minutes (the TTN recommendation); or run ADR on a slower control loop with a high installation margin. Choosing a fixed SF9 or SF10 for a mobile fleet is often a better trade than letting ADR chase a moving target.

Capacity Planning: ALOHA Mathematics and Gateway Density

LoRaWAN uplinks are pure ALOHA: a device transmits whenever its application says so, with no listen-before-talk. That makes capacity analysis tractable and sobering. The numbers in this section are model outputs from standard ALOHA theory and my own arithmetic, not field measurements; real networks differ because of capture effect, non-uniform traffic and imperfect SF orthogonality.

LoRaWAN capacity planning model from device count and airtime to channel load and gateway count

Figure 4: A capacity planning pipeline. Device count, payload size and interval give offered load per channel; the ALOHA success probability then sets the number of devices or gateways that keep delivery above target.

Offered load and collision probability

Define the offered load G on a channel as the average number of frames in flight at any instant: G = N x t_air / (T x C), where N is the number of devices, t_air the frame airtime, T the reporting interval and C the number of channels shared. In pure ALOHA a frame succeeds if no other frame overlaps it, which means no start in a window of twice the frame length, so P(success) = e^(-2G). Channel throughput S = G e^(-2G) peaks at G = 0.5 with S of about 18.4%, but you should never plan near that peak because the delivery ratio there is only e^(-1), 37%.

For a target delivery ratio of 90%, e^(-2G) = 0.9 gives G = 0.053. That is a sound planning ceiling: roughly 5% of channel time occupied.

Worked example: a 15-minute reporting fleet

Take 23-byte frames, one every 900 seconds, spread across three EU868 default channels and all devices on the same SF at the same gateway. The load per device per channel is t_air / (T x C):

  • At SF7 (61.7 ms): 0.0617 / (900 x 3) = 2.29e-5. For G = 0.05, N is about 2,190 devices.
  • At SF9 (205.8 ms): 0.2058 / 2,700 = 7.62e-5, so N is about 655.
  • At SF12 (1,482.8 ms): 1.4828 / 2,700 = 5.49e-4, so N is about 91.

Those three lines are the whole case for ADR. The same gateway and the same three channels carry roughly 24 times more devices at SF7 than at SF12, and the 24 equals the airtime ratio from Figure 2, as it must. If ADR pulls the median device down from SF12 to SF8 or SF9, capacity moves from the low hundreds to the high hundreds or low thousands per gateway. Real fleets have a distribution of spreading factors, so the correct approach is to sum t_air across the SF mix rather than assume one SF.

Quasi-orthogonality improves the picture: different SFs on the same channel do not (mostly) collide, so you can treat each SF as a separate virtual channel for the first-order estimate. That is optimistic but a useful upper bound. Adding more channels, eight is common in EU868 gateways, multiplies capacity linearly.

The capture effect and why it helps the near devices

When two same-SF frames collide, the stronger one often survives if it exceeds the other by about 6 dB, a rule of thumb from the literature with variance across chipsets. Devices close to the gateway therefore win collisions against distant ones. This makes ALOHA’s success formula a pessimistic bound for the near cluster and an optimistic one for the far cluster, which is precisely the group where retransmissions are most expensive.

Gateway density planning

Capacity grows with gateways in two ways. A second gateway lets more devices use low SFs, because path loss to the nearest gateway shrinks and the ADR loop can assign lower SFs. It also provides spatial diversity: a frame lost to a collision at one gateway may be received cleanly at another. Dense networks therefore see the median SF fall as gateways are added, and since airtime scales with 2^SF the capacity gain is superlinear at first.

A practical planning method is:

  1. Survey the device distribution and estimate path loss to candidate gateway sites with a propagation model, calibrating with a few field measurements.
  2. Assign each device the lowest SF whose sensitivity clears its path loss plus your installation margin.
  3. Sum t_air / T over the devices for each SF and channel group to get G.
  4. Add gateways until each SF group stays under G of about 0.05, and until the downlink duty cycle (next section) fits.
  5. Re-run after each ADR cycle with measured SF histograms from the network server.

Dense gateway deployment has a cost the capacity formula hides: every gateway that hears a frame forwards a copy to the network server, which must deduplicate and, in EU868, may schedule the downlink through exactly one of them. Backhaul bandwidth and server load grow with the number of gateways hearing each frame.

Confirmed uplinks request an acknowledgement. Each ack is a downlink, and downlinks are the constrained resource: the gateway is a single transmitter with its own duty cycle, it cannot receive on the same radio while transmitting, and in EU868 a downlink in RX1 uses the same sub-band as the uplink.

Consider 1,000 devices each sending one confirmed uplink every 15 minutes, with SF9 acks lasting about 100 ms (an ack with no payload is a 12-byte PHY frame; I calculate about 0.1 s at SF9 with CRC off, estimate not measurement). The gateway must emit 1,000 / 900 = 1.11 acks per second, i.e. about 11% of the time on air, already over the 1% budget by an order of magnitude when the acks fall in a 1% sub-band. Even with RX2 in the 10% sub-band at SF9, it is saturated. Confirmed uplinks do not scale; use them sparingly, for alarms and commands, and design routine telemetry as unconfirmed with application-level reconciliation.

A retry policy compounds the problem. A device that retransmits a confirmed uplink after a missed ack doubles its airtime and its load on the channel, which raises collision probability for everyone. The specification limits retransmissions via NbTrans and the device-side retry counters, but the right strategy is to avoid confirmation for high-rate telemetry altogether.

Device Classes and Their Energy Cost

LoRaWAN defines three device classes, and the class determines both energy use and downlink latency.

Class A is the default and the lowest power. After each uplink the device opens two short receive windows: RX1 one second after the uplink ends, on the same channel at a data rate derived from the uplink, and RX2 two seconds after, on a fixed channel and data rate. The device sleeps otherwise. Downlinks are possible only in response to an uplink, so latency is bounded by the reporting interval. Class A is the right choice for almost every battery sensor, and ADR commands must ride on those windows.

Class B adds scheduled ping slots synchronised to a beacon from the gateways, which in the specification repeats every 128 seconds. The device wakes at its assigned slots to listen for downlinks, giving bounded latency, such as seconds, without an uplink first. The cost is regular receive energy and the need for accurate timekeeping: crystal drift between beacons must be bounded or the device misses its slots, and gateways must be time-synchronised, usually by GPS.

Class C keeps the receiver open continuously except when transmitting. Latency is minimal, but receive current is tens of times the sleep current of a Class A device, so Class C is for mains-powered devices such as actuators, street-light controllers and valve drivers. Class C also changes the downlink calculus: because the device is always listening, the network can schedule downlinks any time the gateway is free, which makes firmware updates feasible. We cover that case in our guide to FUOTA multicast and fragmentation for LoRaWAN, where downlink capacity again becomes the limiting factor.

A battery-life worked example

Take an illustrative sensor with a radio drawing 45 mA in transmit at 14 dBm, 11 mA in receive, and 2 uA asleep (these are assumed values in the range of common SX127x-based modules, not a specific product; MCU and sensor energy are ignored). It sends one unconfirmed 23-byte uplink every 15 minutes and opens two RX windows of about 0.2 s at SF12 (preamble detection) or about 8 ms at SF7.

  • SF12 transmit: 1.483 s x 45 mA = 66.7 mC, or 18.5 uAh. Two RX windows: 2 x 0.2 s x 11 mA = 4.4 mC, or 1.2 uAh. Sleep for 15 minutes at 2 uA: 0.5 uAh. Total about 20.2 uAh per cycle, or 1.94 mAh per day.
  • SF7 transmit: 0.0617 s x 45 mA = 2.8 mC, or 0.77 uAh. Two RX windows: about 0.04 uAh. Sleep 0.5 uAh. Total about 1.3 uAh per cycle, or 0.126 mAh per day.

On an assumed 2,400 mAh usable battery, the SF12 device lasts about 1,240 days, roughly 3.4 years. The SF7 device computes to decades, which tells you the model has stopped being the binding constraint: battery self-discharge, sensor and MCU energy and temperature effects dominate, so 10 to 15 years is the realistic ceiling. The useful figure is the ratio: moving a device from SF12 to SF7 cuts its radio energy per message by about 15 times in this model. That is the economic argument for ADR in a single number.

Configuring ADR in ChirpStack

ChirpStack’s behaviour is controlled in its TOML configuration and per device profile. Consult the ChirpStack configuration reference for your version; the keys below are those present in its documented EU868 example.

[network]
  # Optional custom ADR algorithms, written in JavaScript.
  adr_plugins = []

[[regions]]
  id = "eu868"

  [regions.network]
    # dB of headroom kept by the ADR engine.
    installation_margin = 10
    # Data-rate bounds the engine may use (EU868 sample values).
    min_dr = 0
    max_dr = 5
    # Set true to turn ADR off for the region.
    adr_disabled = false

Per-device control sits in the device profile, where you can enable or disable ADR for a class of devices, and the device can force it off by clearing the ADR bit. A useful pattern is separate profiles for static meters (ADR on, max_dr as high as the fleet supports), mobile trackers (ADR off, fixed DR), and actuators (ADR on, Class C). If you need different behaviour from the stock engine, such as a downward step on negative margin, implement a custom plugin rather than patching the server. I have not verified the plugin interface details beyond the documentation’s statement that plugins are JavaScript and that a skeleton example is provided; read it before committing to this route.

On TTN, ADR behaviour (documented on the ADR page) includes stopping ADR requests when a device repeatedly refuses them, which usually signals a device bug or a LoRaWAN version mismatch. If you see a device pinned at one data rate despite good SNR, check the downlink logs for LinkADRAns rejections (a rejected data rate, power or channel mask) before blaming the algorithm.

Trade-offs, Gotchas, and What Goes Wrong

ADR is a feedback controller operating through a lossy, rate-limited, high-latency channel. Every classic control failure shows up.

ADR oscillation. If the installation margin is thin and the link fluctuates, the server lowers SF after a good stretch, a few frames are lost at the new rate, the device’s ADRACKReq timer steps SF back up, and the cycle repeats. Each cycle burns downlink airtime and loses frames. Symptoms are a sawtooth in the per-device SF histogram. Fixes: raise the installation margin, use the average rather than the maximum SNR for devices with fading, and lengthen the history window.

Optimistic SNR from a lucky window. Using the maximum SNR over 20 uplinks means one reflection-assisted frame can justify a data rate the link cannot sustain. This is common indoors and with moving objects such as forklifts. Prefer a percentile or the average for those sites.

Interference and the noise floor. SNR margins assume a thermal noise floor. In industrial sites with sub-GHz emitters, a raised floor reduces SNR without reducing RSSI. ADR based on SNR copes better than one based on RSSI, but a persistently noisy channel can also pin devices to high SF. Spectrum scans before deployment are cheap; the factory-wireless alternatives are compared in our private 5G vs Wi-Fi 7 vs TSN decision guide.

Clock drift. Class A devices can survive crude clocks because the receive windows are timed from the end of their own uplink, but the RX windows must still open within a small tolerance, which low-grade RC oscillators can violate at low temperatures. Class B is much less forgiving: drift between beacons must be compensated or ping slots are missed. Budget the timing tolerance in the receive-window opening and widen windows deliberately, at an energy cost.

Downlink duty-cycle exhaustion. A reboot of the network server, a reconfiguration, or a mass join event can trigger ADR requests for the entire fleet at the same time. Gateways drop or delay downlinks past the duty-cycle budget and devices see no ADR commands, then fall back through the device-side backoff, ending up at SF12 simultaneously, which creates exactly the congestion ADR was meant to prevent. Stagger and rate-limit.

Backhaul loss and retained state. ADR state lives on the server. If a gateway loses connectivity and buffers uplinks, the SNR history can be stale. If the server loses state on restart, devices that had converged to SF7 may be forced to rejoin. Persist per-device history and use buffering at the gateway edge where supported; the same store-and-forward ideas apply to the application side, as described in our MQTT edge gateway offline buffering article.

Version and region mismatches. Different LoRaWAN versions (1.0.x vs 1.1) and regional parameter revisions differ in default channels, channel-mask handling and in how ADR ack timers are defined. A device that rejects LinkADRReq because of an unsupported data rate or a bad channel mask will keep trying to recover. Check LinkADRAns status bits in your logs.

Anti-patterns. Fixed SF12 for an entire fleet “to be safe” (it uses 24 times the airtime of SF7 and wastes both capacity and battery); confirmed uplinks for every telemetry frame (downlink saturation); ADR enabled on vehicle-mounted nodes (chasing a moving target); and sizing capacity from a single average SF rather than the SF distribution.

Practical Recommendations

Start from the regulation and the airtime, not the radio. Compute the minimum interval from the airtime of your worst-case SF and payload, confirm it fits the application, and only then choose reporting rates. Shorten the payload: every byte at SF12 costs measurable airtime, while at SF7 it is negligible. Use compact binary encodings rather than JSON, send deltas, and avoid sending data the application can derive.

Keep ADR on for static devices and off, or heavily constrained, for mobile ones. Choose the installation margin from measured field data and revisit it after the first season of weather. Use unconfirmed uplinks for routine telemetry, with a periodic application-level heartbeat so you detect silent devices. Reserve confirmed uplinks and downlinks for alarms, configuration and actuation. Plan capacity from the SF histogram you can measure on the network server, not from the one you hoped for.

Checklist:

  • Look up the regional duty cycle or dwell-time rule and compute the minimum transmit interval per SF.
  • Estimate G per channel and SF group; keep it near or below 0.05 for 90% delivery.
  • Set installation margin per device profile; test with a margin sweep on a pilot group.
  • Separate device profiles for static, mobile and Class C devices.
  • Rate-limit and stagger fleet-wide ADR changes and firmware campaigns.
  • Monitor SF distribution, ADR request/ack ratios, uplink loss and gateway downlink duty cycle.
  • Alert on devices stuck at DR0 despite good SNR (usually a LinkADRAns rejection or channel-mask issue).
  • Re-run the capacity model whenever device count, interval or payload changes.

Frequently Asked Questions

What is LoRaWAN adaptive data rate?

LoRaWAN adaptive data rate (ADR) is a MAC-layer mechanism in which the network server tunes an end device’s spreading factor and transmit power based on measured uplink SNR. Devices with strong links move to lower spreading factors for shorter airtime, saving battery and channel capacity, while distant devices keep higher spreading factors for range. The device opts in via the ADR bit, and the server issues LinkADRReq commands to change settings.

Should ADR be enabled for mobile LoRaWAN devices?

Generally no. ADR assumes a stable link, because the server averages SNR over many uplinks and applies changes only after a downlink. A moving device’s path loss changes faster than the loop reacts, causing lost frames or wasteful high spreading factors. The Things Network advises mobile devices to enable ADR only after detecting they have been stationary for a while; otherwise, fix the data rate for worst-case coverage.

How long does a LoRa packet take to transmit at each spreading factor?

It depends on payload, bandwidth and coding rate. For a 23-byte PHY payload (10 bytes of application data plus 13 bytes of LoRaWAN overhead) at 125 kHz and coding rate 4/5, the standard Semtech formula gives about 62 ms at SF7, 206 ms at SF9, 371 ms at SF10 and 1.48 s at SF12. Each spreading factor step roughly doubles airtime, so SF12 is about 24 times SF7.

What is the LoRaWAN duty cycle limit and how does it affect message rate?

In EU868 most sub-bands are limited to 1% duty cycle, with 0.1% and 10% sub-bands also defined. At 1%, a device must wait about 99 times the frame airtime before transmitting again on that sub-band, so a 1.48 s SF12 frame implies roughly 148 s between uplinks, while SF7 allows about 6 s. US915 uses a 400 ms dwell time rather than a duty cycle.

How many devices can one LoRaWAN gateway support?

There is no single figure. Pure ALOHA theory gives 90% uplink success at about 5% channel load, which for 23-byte frames every 15 minutes across three channels works out to around 2,000 devices at SF7 but fewer than 100 at SF12 (model output, not a measurement). Real capacity depends on spreading-factor mix, channel count, capture effect, interference and downlink demand, so measure and re-plan.

Why is my device stuck at SF12 even though the signal is strong?

Common causes are ADR disabled in the device or profile, a device that never sets the ADR bit, a regional channel mask or data-rate limit that the server cannot satisfy, repeated rejection of LinkADRReq (a version or region mismatch), or an installation margin set so high that no step is allowed. Check the ADR flag in uplinks and the LinkADRAns status in downlink logs first.

Further Reading

Capacity and battery figures in this article are model calculations from stated assumptions, not field measurements. Validate against your radios, regions and site conditions.

By Riju — about

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *