Queuing mechanisms like LLQ are about managing the front of our queues. RED (Random Early Detection) is about managing the tail of our queue.
When a queue is full, there is no room for any more packets and the router drops packets that should have been queued. This is called tail drop.

Data traffic is usually bursty so when tail drop occurs, the router probably drops multiple packets. Tail drop is bad, especially for TCP traffic.
The TCP window size increases automatically but when TCP segments are dropped, it reduces back to one segment. The window size then grows exponentially until it reaches half the window size of what it was when the congestion occurred. The TCP window size then grows linearly. This process is called slow start and explained in detail in the TCP window size scaling lesson.
The problem with this behavior of TCP is that you probably don’t have just one TCP connection but multiple TCP connections. When the queue is full and tail drop occurs, everything is discarded and all TCP connections use slow start. We call this TCP global synchronization and it looks like this:

To increase overall throughput, we can use a technique called RED (Random Early Detection). Instead of waiting for tail drop to happen, we monitor the queue depth. When the queue starts to fill up, we discard some random packets with the goal of slowing down TCP. The “weighted” part of WRED is that WRED monitors the average queue depth. When the queue starts to fill, it will only drop a few random packets. When the queue length increases, it becomes more aggressive and drops even more random packets until it hits a certain limit. When this limit is reached, all packets are dropped.
Here’s how to visualize this:

This graph has an X and Y axis:
- Average queue depth: this is the length of our queue and for now, let’s say this represents the number of packets in the queue.
- Discard probability: the chance in % that WRED drops our packets.
What do the different numbers mean? WRED uses a traffic profile for the packet drop probability based on the following three items:
- Minimum threshold: 20 packets
- Maximum threshold: 45 packets
- MPD (Mark Probability Denominator): 25%
These values can be configured of course.
Here’s how it works:
- When the average queue depth is below the minimum threshold (20), WRED doesn’t drop any packets at all.
- When the average queue depth is above the minimum threshold (20), WRED starts to drop a small number of random packets.
- When the average queue depth increases even further, WRED drops a larger % of random packets until we reach the maximum threshold (45).
- When the average queue depth reaches the maximum threshold (45), WRED drops all packets.
- The MPD (25%) is the number of packets that WRED drops when we hit the maximum threshold (45).
The default option for these thresholds is the number of packets but you can also use the number of bytes or even milliseconds/microseconds for these thresholds. The number of packets is the most common option.
We can summarize this in a table:
Average queue depth | Action | WRED action name |
average queue depth < minimum threshold | No packets are dropped. | No drop |
average queue depth > minimum threshold AND average queue depth < maximum threshold | Percentage of packets is dropped. This percentage increases to a maximum (MPD) until we reach the maximum threshold. | Random drop |
Average queue depth > maximum threshold | All packets are dropped. This is the same as tail drop. | Full drop |
Dropping all packets when we hit an artificial maximum threshold might sound weird. How is that any better than “regular” tail drop?
Some packets are more important than others so instead of dropping completely random packets, we use different traffic profiles for different packets. We can discard packets based on criteria like the CoS, IP Precedence, DSCP, and some other options.
Here is a quick example of two traffic profiles:

Above, we have two different traffic profiles. One for packets marked with IP precedence 3 and another one for IP precedence 5:
- IP Precedence 3:
- minimum threshold: 20 packets
- maximum threshold: 45 packets
- MPD: 25%
- IP Precedence 5:
- minimum threshold: 30 packets
- maximum threshold: 60 packets
- MPD: 20%
We drop IP precedence 3 packets earlier (minimum threshold 20 packets) and more often (MPD 25%) than IP precedence 5 packets.
Instead of IP precedence, we can also use DSCP. WRED then sets a minimum threshold based on the drop probability that we have seen in the IP precedence and DSCP values lesson:
Drop | Class 1 | Class 2 | Class 3 | Class 4 |
Low | AF11 | AF21 | AF31 | AF41 |
Medium | AF12 | AF22 | AF32 | AF42 |
High | AF13 | AF23 | AF33 | AF43 |
Within the same class, AFx3 has a higher drop probability than AFx1. For example, AF13 is dropped sooner than AF11.
WRED works with IP precedence and DSCP but you can also use it for CoS, (ATM) cells, or discard-class values. DSCP is the most common option.
WRED needs a queue to work and it doesn’t work for all queuing mechanisms. You can configure it on:
- Physical interfaces with FIFO queue
- Regular queues in CBWFQ (not the priority queue)
- ATM VC
Some other important things to understand about WRED:
- All non-IP traffic is treated as unmarked traffic so it has a higher chance of getting dropped.
- WRED is only useful for TCP traffic because it tells TCP that the network is congested and the TCP window size is reduced. There is no point dropping UDP packets and it will only make things worse if you have real-time traffic like VoIP.
- Traffic from sources that generate most of the traffic is dropped most often. When the network is congested, these traffic sources will be slowed down more than other sources generating less traffic.
In the remaining of this lesson, I will show you how to configure WRED on a Cisco IOS router.
I use the following topology to demonstrate WRED:

We’ll send traffic from R1 to R3 and on R2 we configure WRED. There used to be an interface-level command for WRED but it has been deprecated for a few years now. In these examples, I will use MQC.
- Configurations
- R1
- R2
- R3
Want to take a look for yourself? Here you will find the startup configuration of each device.
IP Precedence
The default setting in WRED is to look for IP precedence values. Let’s configure a policy-map and enable WRED:
R2(config)#policy-map WRED
R2(config-pmap)#class class-default
R2(config-pmap-c)#random-detect
You only need to add the random-detect
command, that’s easy enough. Let’s enable the policy-map on the GigabitEthernet 0/2 interface of R2:
R2(config)#interface GigabitEthernet 0/2
R2(config-if)#service-policy output WRED
Let’s take a look at that policy-map:
R2#show policy-map interface GigabitEthernet 0/2
GigabitEthernet0/2
Service-policy output: WRED
Class-map: class-default (match-any)
47 packets, 4972 bytes
5 minute offered rate 0000 bps, drop rate 0000 bps
Match: any
queue limit 64 packets
(queue depth/total drops/no-buffer drops) 0/0/0
(pkts output/bytes output) 47/4972
Exp-weight-constant: 9 (1/512)
Mean queue depth: 0 packets
class Transmitted Random drop Tail drop Minimum Maximum Mark
pkts/bytes pkts/bytes pkts/bytes thresh thresh prob
0 47/4972 0/0 0/0 20 40 1/10
1 0/0 0/0 0/0 22 40 1/10
2 0/0 0/0 0/0 24 40 1/10
3 0/0 0/0 0/0 26 40 1/10
4 0/0 0/0 0/0 28 40 1/10
5 0/0 0/0 0/0 30 40 1/10
6 0/0 0/0 0/0 32 40 1/10
7 0/0 0/0 0/0 34 40 1/10
Above, we see all possible IP precedence values and the different traffic profiles. By default, only the minimum threshold is different. Higher IP precedence values have a higher minimum threshold. We see a number of packets have been transmitted but nothing has been dropped yet.
To see WRED in action, I’ll add a shaper to our policy-map since it’s difficult to congest a gigabit interface. Let’s shape to 1000 kbps:
R2(config)#policy-map WRED
R2(config-pmap)#class class-default
R2(config-pmap-c)#shape average 1000k
Let’s send a couple of pings from R1. Since my pings use ICMP it won’t slow down R1’s traffic rate but we will see that R2 drops these packets. I’ll send enough traffic to trigger random drops but not enough to trigger tail drops:
R1#ping 192.168.23.3 repeat 1000000 size 160 timeout 0
Here are the results:
R2#show policy-map interface GigabitEthernet 0/2 | begin Transmitted
class Transmitted Random drop Tail drop Minimum Maximum Mark
pkts/bytes pkts/bytes pkts/bytes thresh thresh prob
0 14268/2482290 23/4002 0/0 20 40 1/10
1 0/0 0/0 0/0 22 40 1/10
2 0/0 0/0 0/0 24 40 1/10
3 0/0 0/0 0/0 26 40 1/10
4 0/0 0/0 0/0 28 40 1/10
5 0/0 0/0 0/0 30 40 1/10
6 0/0 0/0 0/0 32 40 1/10
7 0/0 0/0 0/0 34 40 1/10
shape (average) cir 1000000, bc 4000, be 4000
target shape rate 1000000
This is looking good. We can verify that R2 has dropped some random packets.
Traffic Profile
You have now seen WRED in action and we only required a single command to enable it. Let’s see what configuration options we have:
R2(config)#policy-map WRED
R2(config-pmap)#class class-default
R2(config-pmap-c)#random-detect ?
atm-clp-based Enable atm-clp-based WRED as drop policy
clp parameters for each clp value
cos parameters for each cos value
cos-based Enable cos-class-based WRED as drop policy
discard-class parameters for each discard-class value
discard-class-based Enable discard-class-based WRED as drop
policy
dscp parameters for each dscp value
dscp-based Enable dscp-based WRED as drop policy
ecn explicit congestion notification
exponential-weighting-constant weight for mean queue depth calculation
precedence parameters for each precedence value
precedence-based Enable precedence-based WRED as drop policy
There are two things we can configure here:
- Change the drop policy to use a different value. For example, we can switch from IP precedence based to DSCP based.
- Change the traffic profile(s) of the drop policy.
Let’s stick to IP precedence for now and tune it a bit. We can configure the traffic profile for each IP precedence value with the random-detect precedence
command:
R2(config-pmap-c)#random-detect precedence ?
<0-7> IP precedence
rsvp rsvp traffic
Let’s say we want to change the settings for IP precedence 4:
R2(config-pmap-c)#random-detect precedence 4 ?
<1-262143> minimum threshold (in packet by default)
Let’s change the minimum threshold to 30 packets:
R2(config-pmap-c)#random-detect precedence 4 30 ?
<1-262143> maximum threshold (in packet by default)
bytes number of bytes
ms milliseconds
packets in packets
us microseconds
The default setting is packets but if you want, you can also use the number of bytes or milliseconds/microseconds. Let’s set the maximum threshold to 35 packets:
R2(config-pmap-c)#random-detect precedence 4 30 35 ?
<1-65535> mark probability denominator
packets in packets
The last setting is the MPD and it’s also configured in the number of packets. When you set it to a value, it means “1 out of X packets” where X is the value you configure. For example:
- MPD 4 is “1 out of 4” packets which equals 25%.
- MPD 5 is “1 out of 5” packets which equals 20%
- MPD 20 is “1 out of 20” packets which equals 5%
Let’s set it to 20 packets:
R2(config-pmap-c)#random-detect precedence 4 30 35 20
That completes the traffic profile configuration. Let’s test it by sending some more traffic from R1 and adding a TOS value of decimal 128 (that’s IP precedence 4):
R1#ping 192.168.23.3 repeat 1000000 size 165 timeout 0 tos 128
Let’s check R2:
R2#show policy-map interface GigabitEthernet 0/2
GigabitEthernet0/2
Service-policy output: WRED
Class-map: class-default (match-any)
4055 packets, 725845 bytes
5 minute offered rate 17000 bps, drop rate 1000 bps
Match: any
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer drops) 30/88/0
(pkts output/bytes output) 3967/710093
Exp-weight-constant: 9 (1/512)
Mean queue depth: 31 packets
class Transmitted Random drop Tail drop Minimum Maximum Mark
kts/bytes pkts/bytes pkts/bytes thresh thresh prob
0 0/0 0/0 0/0 20 40 1/10
1 0/0 0/0 0/0 22 40 1/10
2 0/0 0/0 0/0 24 40 1/10
3 0/0 0/0 0/0 26 40 1/10
4 3968/710272 88/15752 0/0 30 35 1/20
5 0/0 0/0 0/0 30 40 1/10
6 0/0 0/0 0/0 32 40 1/10
7 0/0 0/0 0/0 34 40 1/10
shape (average) cir 1000000, bc 4000, be 4000
target shape rate 1000000
bandwidth 1000 kbps
Very nice, we can see our new thresholds and we confirm that R2 is dropping some random packets that are marked with IP precedence 4.
DSCP
Enough IP precedence, let’s switch to DSCP based drops. To do this, we need to disable the IP precedence based drop policy and enable DSCP based:
R2(config)#policy-map WRED
R2(config-pmap)#class class-default
R2(config-pmap-c)#no random-detect precedence-based
R2(config-pmap-c)#random-detect dscp-based
Let’s take a look at our policy-map:
R2#show policy-map interface GigabitEthernet 0/2 | begin Transmitted
dscp Transmitted Random drop Tail drop Minimum Maximum Mark
pkts/bytes pkts/bytes pkts/bytes thresh thresh prob
default 8/802 0/0 0/0 20 40 1/10
On my router, it doesn’t show me all possible DSCP values. It only shows those that the router has seen. Let’s verify this by sending some more packets from R1. I’ll send packets with a TOS value of 184 (DSCP EF):
R1#ping 192.168.23.3 repeat 1000000 size 165 timeout 0 tos 184
This will show up on R2:
R2#show policy-map interface GigabitEthernet 0/2
GigabitEthernet0/2
Service-policy output: WRED
Class-map: class-default (match-any)
6926 packets, 1239345 bytes
5 minute offered rate 29000 bps, drop rate 0000 bps
Match: any
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer drops) 0/47/0
(pkts output/bytes output) 6879/1230932
shape (average) cir 1000000, bc 4000, be 4000
target shape rate 1000000
bandwidth 1000 kbps
Exp-weight-constant: 9 (1/512)
Mean queue depth: 2 packets
dscp Transmitted Random drop Tail drop Minimum Maximum Mark
pkts/bytes pkts/bytes pkts/bytes thresh thresh prob
default 6/665 0/0 0/0 20 40 1/10
ef 6873/1230267 47/8413 0/0 36 40 1/10
Above, we see the packets marked with DSCP EF and a couple of random drops. We see the minimum threshold (36) is much higher than the value for unmarked traffic (20).
Earlier, I explained that WRED looks at the drop probability of different DSCP values. Let’s see if this is true, to test this I will send a couple more pings with TOS values that match AF11, AF12, AF13, AF21, AF22, and AF23:
R1#
ping 192.168.23.3 repeat 1 tos 40
ping 192.168.23.3 repeat 1 tos 48
ping 192.168.23.3 repeat 1 tos 56
ping 192.168.23.3 repeat 1 tos 72
ping 192.168.23.3 repeat 1 tos 80
ping 192.168.23.3 repeat 1 tos 88
Here’s the result:
R2#show policy-map interface GigabitEthernet 0/2
GigabitEthernet0/2
Service-policy output: WRED
Class-map: class-default (match-any)
8 packets, 804 bytes
5 minute offered rate 0000 bps, drop rate 0000 bps
Match: any
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer drops) 0/0/0
(pkts output/bytes output) 8/804
shape (average) cir 1000000, bc 4000, be 4000
target shape rate 1000000
bandwidth 1000 kbps
Exp-weight-constant: 9 (1/64)
Mean queue depth: 0 packets
dscp Transmitted Random drop Tail drop Minimum Maximum Mark
pkts/bytes pkts/bytes pkts/bytes thresh thresh prob
default 2/120 0/0 0/0 20 40 1/10
af11 1/114 0/0 0/0 32 40 1/10
af12 1/114 0/0 0/0 28 40 1/10
af13 1/114 0/0 0/0 24 40 1/10
af21 1/114 0/0 0/0 32 40 1/10
af22 1/114 0/0 0/0 28 40 1/10
af23 1/114 0/0 0/0 24 40 1/10
Above, you can see that the minimum threshold is based on the drop probability. For example, AF23 has a higher drop probability even though AF11 is in a “lower” class.
Exponential Weighting Constant
If you looked closely at the output of the previous policy-maps, you might have seen this line:
R2#show policy-map interface GigabitEthernet 0/2 | include weight
Exp-weight-constant: 9 (1/512)
This is not something to worry about but it could be important to know when studying for an exam. WRED calculates an average queue depth and this average is updated based on the exponential weighting constant. The following formula is used for this calculation:
average = old_average + (instantaneous – old_average) / 2^exponential-weighting-constant
Instantaneous is the instantaneous queue depth, reported by hardware. The router makes tail drop decisions based on this queue depth. The average queue depth is calculated by combining the current average and old average and dividing the result with the exponential-weighting-constant. Based on this formula:
- A high exponential weighting constant will result in smaller average queue depth values.
- A low exponential weighting constant will result in larger average queue depth values.
In other words, a low exponential weighting constant will make WRED respond to changes quickly and a high exponential weighting constant will make WRED respond slowly to changes.
It’s best to leave this setting alone unless but if you want to change it, here’s how to do this:
R2(config)#policy-map WRED
R2(config-pmap)#class class-default
R2(config-pmap-c)#random-detect exponential-weighting-constant ?
<1-16> integer in 1..16 used in weighted average to mean 2^number
The default value on Cisco IOS is 9. Let’s change it to 6:
R2(config-pmap-c)#random-detect exponential-weighting-constant 6
That’s all there is to it.
Conclusion
This is the end of the WRED lesson. You have now learned:
- That WRED can be used to manage the “tail” of your queue and that it’s a mechanism to try and prevent tail drop.
- Tail drop is bad for TCP traffic because of the TCP slow start mechanism and TCP global synchronization.
- WRED calculates the average queue depth and drops random packets before tail drop occurs.
- We use a traffic profile that uses three items:
- Minimum threshold
- Maximum threshold
- MPD (Mark Probability Denominator)
- Traffic is dropped based on the following criteria:
- average queue depth < minimum threshold: don’t drop
- average queue depth > minimum threshold AND average queue depth < maximum threshold: drop a % of packets
- average queue depth > maximum threshold: full drop
- Traffic profiles can be configured for different drop policies, the most common options are IP precedence and DSCP based.
- Traffic profiles can be customized: you can change the minimum/maximum threshold and MPD for each possible value in your drop policy.
I hope you enjoyed this lesson. If you have any questions feel free to leave a comment!