Description

We explained how load balancing works on aggregated Ethernet interfaces, why traffic is not always evenly distributed across their child interfaces, and how this process can be optimized. We also reviewed the differences between "per‑packet" and "per‑flow" load balancing, highlighting the advantages and benefits of each load‑balancing method, along with their considerations, helps ensure the most effective traffic distribution strategy.

Symptoms

  • Ethernet aggregated formed of high amount of child interfaces, which makes effective load balancing challenging.
  • Congestion is observed on some links within the LAG, while others show low utilization.
  • Traffic is not being evenly distributed across all child interfaces.

Solution

The LAG hashing algorithm on EX/QFX Series switches determines the member link to be used for an incoming frame/packet depending on a subset of the following values in the frame/packet header:

 

  • Source MAC address.
  • Destination MAC address.
  • Ether type.
  • VLAN id.
  • Source IP address.
  • Destination IP address.
  • Protocol (for IPv4 packets).
  • Next header (for IPv6 packets).
  • L4 source port.
  • L4 destination port.
  • MPLS label.

 

The hashing algorithm also takes into account the type of "frame/packet" when determining the outgoing member link, distributing traffic across the child interfaces accordingly. This process is based solely on the hashing algorithm and occurs dynamically.

 

In complex Ethernet topologies, traffic imbalances occur due to increased traffic flow, and load balancing becomes challenging for some of the following reasons:

 

  • Incorrect load balancing by aggregate next hops.
  • Incorrect packet hash computation.
  • Insufficient variance in the packet flow.
  • Incorrect pattern selection.

 

As a result of traffic imbalance, the load is not being properly distributed, causing congestion on certain links while others remain underutilized. For example, the following device has 12 child interfaces forming an aggregated Ethernet interface on ae0, traffic is not evenly spread across all members—some interfaces show similar utilization while others remain almost idle:

 

root@user> monitor interface traffic 


Interface  Link Input packets    (pps)   Output packets    (pps)

 xe-0/0/1  Up   1984807770     (1)    640965676     (1)
 xe-0/0/2  Up     75475     (1)    1326217796     (1)
 xe-0/0/3  Up     75413     (1)    2032951056  (3379836)
 xe-0/0/4  Up     77961     (1)     65972106  (3379834)
 xe-0/0/5  Up     76170     (1)     87256427     (0)
 xe-0/0/6  Up    48391021  (3377791)     66141743  (3377793)
 xe-0/0/7  Up   2081604065  (6755580)      79751     (0)
 xe-0/0/8  Up     75450     (1)    2718596133  (3377790)
 xe-0/0/9  Up     77988     (1)    553793350     (1)
 xe-0/0/10  Up   1984807033     (1)    553785615     (1)
 xe-0/0/11  Up   1984806303     (1)     87256426     (1)
 xe-0/0/12  Up    55538702  (3377779)      75378     (1)
 ae0      Up   8140413351  (13511159)    8133091457  (13515259)

 

Junos operates by default on load balance "per flow" and not on the "per packet", and there are consideration for the "per packet" balancing, as packets of the same flow going through different links may arrive in different. 


Unfortunately, we can’t equally load the balance the traffic in LAG child interface as its happened dynamically based on the LAG hashing algorithm. The load balancing on ae works on "per flow" basis, not "per packet", so there will not be a proper load-balancing that takes place on an ae interface.

 

Traffic flow example when using  default load balance "per-flow"

 

If there is a huge file transfer from IP .101 to IP .102, let’s say 20G of traffic and there is another file transfer of just 100mb from IP .101 to IP .103, then load balance will happen as "per flow". It will consider the first transfer one flow (20G of traffic) and the other one a second flow (100mb), and hence, we ended up using one link for 20G while the other link for only 100mb. Here, we still have load balance happening; however, based on the flow.

 

What can be change is what is consider a flow, just IP source and destination, or we could also take the port, or labels, etc into consideration. However, even if you take those into consideration for the algorithm, we will not end up with 10G on one link and another 10G on the other, if it was just one flow, it will go through just one link typically would be multiple, as communication usually is not 1 to 1 but they may see 70% on one link and only 30% on another.

 

You can enabled "enhanced-hash-key" when working with "per-flow" load balance to optimize this  procedure:

 

root@user# set forwarding-options enhanced-hash-key hash-parameters lag preprocess enable
root@user# commit

 

After this change, you will see the "hash preprocess" changing from 0 to 1 as follows:

 

root@user> show forwarding-options enhanced-hash-key 

Slot 0
Hash-Parameter Settings for LAG
------------------------------------------------------------
Hash Function = CRC32_HI
Hash offset base = 16
Hash offset = 10
Hash preprocess = 0     >> Not enabled.
 
 Fabric Load Balancing Options
 ------------------------------------------------------------
   Load Balancing Method  : Enhanced Hash

 

After the commit:

 

root@user> show forwarding-options enhanced-hash-key 

Slot 0
Hash-Parameter Settings for LAG     
------------------------------------------------------------
Hash Function = CRC32_HI         
Hash offset base = 16          
Hash offset = 10             
Hash preprocess = 1     >> Enabled.         
                    
 Fabric Load Balancing Options     
 ------------------------------------------------------------
   Load Balancing Method  : Enhanced Hash

 

When "hash preprocess" is enabled, thes witch performs additional preprocessing/mixing of the hash inputs before the final LAG hash calculation, this commands is useful because improves traffic distribution when:

 

  • Many flows have similar addresses.
  • You have large ECMP + LAG deployments.
  • You see uneven utilization across bundle members.
  • Traffic patterns produce poor entropy.

 

Without preprocessing, certain traffic patterns can hash disproportionately to a subset of links. With preprocessing enabled:

 

  • Better entropy is generated.
  • More flows spread across all AE members.
  • Hot spots are reduced.


What it does not do:

 

  • Rehash existing flows mid-session.
  • Change packet contents.
  • Affect routing decisions.
  • Increase bandwidth.

 

It only changes how the switch selects the member link for a flow. However, when multiple interfaces are part of the same aggregated Ethernet interface, the load‑balancing process becomes more complex—especially when using "per‑flow" load balancing. With "per‑flow", traffic cannot be evenly distributed across all child interfaces of a LAG, since the assignment occurs dynamically based on the hashing algorithm.

 

Load balance "per-flow":

All traffic belonging to the same flow is forwarded by the system through a single egress interface. For example, the slide illustrates two distinct traffic flows that Switch 1 forwards out of ge‑0/0/2 and ge‑0/0/3, which are the egress interfaces associated with the equal‑cost paths leading to the destination network.

 

Due to the nature of the load balance "per-flow", it maintains individual traffic flows between end stations, which results in a number of benefits. One benefit is that the packets generally arrive at the destination in the order they were sent.

 

Thus, the end station does not have to reorder the packets, and the applications experience less delay. In addition, because similar user traffic uses the same path through the network, network-wide policies such as quality of service (QoS) are easier to implement. All protocols—not just TCP—can benefit from the establishment of flows through a network.

 

By default, the Junos operating system considers traffic that enters the same ingress interface and has the same source and destination addresses and the same protocol a single flow. 

 

Load balance "per-packet":

 

When a device uses "per‑packet" load balancing, packets are forwarded in a round‑robin fashion across the egress interfaces connected to equal‑cost paths toward the destination. While this method can evenly distribute traffic, it may also reduce performance.

 

For example, on the topology above, Switch 1 sends Packet A out one interface and Packet B out the other interface to Switch 2, then Switch 2 receives both packets and forwards them on to the destination. There is no guarantee that Switch 2 will receive and process Packet A before Packet B. Assuming that both packets belong to a common session (or flow), this out-of-sequence processing might require the destination device to reorder the packets or the source device to retransmit the packets, thus causing a reduction in performance.

 

You can change the load‑balancing behavior to "per‑packet" only on the specific aggregated Ethernet interface. This adjustment distributes the traffic across the child interfaces of the aggregated Ethernet port:

  

root@user# set interfaces ae0 aggregated-ether-options dlb per-packet   

root@user# commit 

 

root@user> monitor interface traffic 

 

Interface  Link Input packets    (pps)   Output packets    (pps)

 xe-0/0/1  Up   1997747281  (1123512)    652109642  (1124869)
 xe-0/0/2  Up    13090540  (1128571)    1337418533  (1127683)
 xe-0/0/3  Up    13113167  (1127749)    2305919896  (1127614)
 xe-0/0/4  Up    13106898  (1123161)    338872078  (1124300)
 xe-0/0/5  Up    13133937  (1123668)     98508006  (1124062)
 xe-0/0/6  Up   317592553  (1126323)    338942614  (1126216)
 xe-0/0/7  Up   2606738925  (1126607)     11409832  (1127060)
 xe-0/0/8  Up    13242964  (1127345)    2991277362  (1126223)
 xe-0/0/9  Up    13268083  (1128242)    565170388  (1127329)
 xe-0/0/10  Up   1998019441  (1128054)    565198653  (1127942)
 xe-0/0/11  Up   1998054731  (1126876)     98688556  (1126253)
 xe-0/0/12  Up   317703189  (1123245)     11496184  (1123723)
 ae0      Up   9314811709  (13513353)    9315011744  (13513274)

 

Since "per‑flow" load balancing cannot guarantee equal distribution, if the goal is to spread traffic evenly across all links in the aggregated Ethernet, we can enable "per‑packet" load balancing only on the aggregation interface. The command enables Dynamic Load Balancing "per‑packet" specifically on the interface. You can check more information on the following link:

 

https://www.juniper.net/documentation/us/en/software/junos/interfaces-ethernet-switches/topics/topic-map/dynamic-load-balancing.html

 

This decision should take into account the benefits and limitations of each load‑balancing method, as well as the characteristics of the traffic flow to ensure that performance is not degraded when using "per‑packet" load balancing.

Modification History

2026-06-16 : Article Created