Offloading RX2 frequency in the deployment area, by running multiple LNS with different RX2


In our case we have already deployed lorawan network and now we trying to improve the reliability of the network.
Our solution uses Class C devices, and quite intensive downlink communication is possible in the deployed area.
In order to reduce the number of downlink collisions, we have an idea to use a different value of RX2 for different gateways/devices. In order to do that we plan to run 8 Network Servers with different RX2 frequency (923.3 - 927.5, step 600 KHz) that will be connected to one Application Server.

Let’s imagine that we have three devices(Device 1,2,3) that are connected to two gateways(Gateway 1, 2). All devices use the default settings like in the specification for our region ( RX2=923.3). We have two gateways(Gateway 1, Gateway 2) in the deployment area that are connected to the same network server (Network server 1), and the network server is configured to use RX2 923.3. Also we have another network server(Network server 8) that is configured to use RX2 927.5, but no gateway is connected to this network server yet.

In this step we have:

  • Device 1 working on Subband 1 with RX2 923.3 connected to Gateway 1, which connected to Network server 1
  • Device 2 working on Subband 1 with RX2 923.3 connected to Gateway 1, which connected to Network server 1
  • Device 3 working on Subband 2 with RX2 923.3 connected to Gateway 2, which connected to Network server 1

After some time, we notice that we have collisions on downlinks and we decide to offload the RX2 frequency. Since we have Network server 8, which operates on a different RX2 frequency(927.5), we decided to route Gateway 2 to this server. We go to Gateway 2 and reconfigure it to Network Server 8 and restart Gateway 2.
After the configuration, Network Server 8 should send RXParamSetupReq MACcommand to all devices, in our case, to the Device 3.

In the documentation mentioned that
Note: on a ChirpStack Network Server configuration change, the new parameters will be pushed to the device using the RXParamSetupReq or RXTimingSetupReq mac-commands at the first opportunity.

My questions is:

  • What does it mean - at the first opportunity? Will an RXParamSetupReq be sent to the device after the next JoinRequest in the RX1 window?
  • RXParamSetupReq is sent only in RX1 window, or it can be sent in RX2 window as well(if so on what RX2 frequency? the old one?).
  • Do you think this approach is generally suitable for solving the RX2 frequency downlink collision problem?

I attached a small diagram, maybe it will add understanding to the my text…

The RXParamSetupReq mac-command is sent to the device the NS detects that the parameters of the device-session are different from the configuration file. Once the device acknowledges the RXParamSetupReq, the NS will update the device-session with the updated parameters. This works on both RX1 and RX2, but please note that mac-commands are sent using Class-A only.

Would a better approach be to add support for multiple rx2 frequencies, and assign these randomly to devices (during the lifetime of the activation)?

Hello Brocaar

Thank you for response!

Can you elaborate more on this solution that you mentioned? Where should support for multiple rx2 frequencies be added? On the side of the network server? Can one network server run on different RX2 frequencies?

Now we have the following plan: in the deployment area we will have several gateways that will work on different uplink subbands (1-8), the node device will randomly select one of the subbands, and if, for example, the device connects to the gateway with subband 1, then we set rx2 frequency 923.3, and if to the gateway with subband 2 then we set rx2 frequency 923.9 and so on.

But it is not clear to us how we should design the architecture of the server side in order to ensure such a logic of work. Do we need 8 network servers with different rx2 frequncies or can we do something differently?

Thank you!

In your case, you need to have 8 ChirpStack Network Server instances, each with their own sub-band configuration. I think this is quite some overhead. Also, it means that each uplink is only received by 1/8th of your gateways (assuming an even distribution of gateway configs). I don’t think a setup like this should be required as it means that one area is covered by at least 8 gateways (each configured to its own sub-band), which might be quite some overhead.

I think it should be possible to use a single sub-band (thus all gateways with the same config), but use multiple RX2 frequencies. The RX2 freq. is negotiated between the NS and device and does not depend on any gateway configuration (apart from that it needs to be within the min and max tx frequencies).

The idea that I’m proposing a config option like:

rx2_frequencies = [

On OTAA join, the NS would randomly assign one of the rx2_frequencies to a device. It would only change when it joins again or when you remove that frequency from the rx2_frequencies list.

Also, it means that each uplink is only received by 1/8th of your gateways (assuming an even distribution of gateway configs)

In our device firmware, once it successfully joins and the rssi/snr on the join accept is above our tolerance, the channel mask is automatically updated to limit the channels to that sub-band. So, the join operation is fundamentally not only a join, but also a network “probe”, so to speak, in order to determine which sub-band the device should operate on.

On OTAA join, the NS would randomly assign one of the rx2_frequencies to a device

A random downlink channel per device won’t 100% solve the downlink collision issue. If all devices are randomly assigned a downlink channel, then GW1 and GW2 will still downlink on the same frequency from time to time (1/8 chance I suppose). Perhaps this is a good enough improvement, we will discuss and test internally.

We could also modify the LNS: Instead of randomly choosing an RX2 frequency from the list, it chooses the downlink frequency index based on what subband the join occurred on. Is the join request metadata (mainly the uplink frequency) available when it assigns the random rx2_frequencies?