When a WAN link congests, something has to give, and QoS is how you decide what. Left to itself, a link under load treats a voice packet exactly like a bulk file transfer, and the call breaks while the download barely notices. Low Latency Queueing and Class-Based Weighted Fair Queueing are the tools that let you say "voice goes first, always, and everything else shares what is left fairly." This article builds the full queueing policy on Cisco IOS XE and then congests a real link to prove the priority class is protected.
It extends the QoS cluster guide.
Queueing Only Matters When the Link Is Full
The first thing to internalise: queueing does nothing on an uncongested link. If packets can leave as fast as they arrive, there is no queue to manage. Queueing policy only takes effect when traffic arrives faster than the interface can send it, so packets have to wait in a queue, and which queue, and in what order they drain, is what QoS decides.
So the whole subject is about behaviour under congestion. To demonstrate it honestly you have to actually congest a link, which is exactly what the lab does: a 5 Mbps choke point with a bulk transfer saturating it and a voice-marked flow competing for the same pipe.
The Distinction Everyone Confuses: priority vs bandwidth
LLQ and CBWFQ are configured with two commands that look similar and behave completely differently. Getting this straight is the core of the topic:
The mental model: priority is a fast lane that is always serviced first (but capped, so it cannot starve everything else). bandwidth is a reserved minimum share of a shared road. Voice needs the fast lane because a late voice packet is a useless voice packet. A database replication job needs a guaranteed minimum but does not care about a few milliseconds of delay, so it gets bandwidth.
The critical subtlety: LLQ's priority queue is policed. It is serviced first, but only up to its configured rate; traffic above that rate is dropped. This is deliberate and essential, because an unpoliced strict-priority queue could consume the entire link and starve every other class. The policer is what makes strict priority safe.
Building the Policy
Three steps: classify (class-maps), define behaviour (policy-map), apply (service-policy). The classification here uses DSCP, assuming traffic is already marked (marking is upstream, at the network edge).
R1(config)# class-map match-all EF-VOICE
R1(config-cmap)# match dscp ef
R1(config)# class-map match-all BULK-DATA
R1(config-cmap)# match dscp af11
!
R1(config)# policy-map WAN-EDGE
R1(config-pmap)# class EF-VOICE
R1(config-pmap-c)# priority percent 20
R1(config-pmap)# class BULK-DATA
R1(config-pmap-c)# bandwidth percent 40
R1(config-pmap-c)# random-detect dscp-based
R1(config-pmap)# class class-default
R1(config-pmap-c)# fair-queue
R1(config-pmap-c)# random-detect
!
R1(config)# interface Ethernet0/2
R1(config-if)# service-policy output WAN-EDGERead the policy as a set of promises. EF-VOICE (matched on DSCP EF, the standard voice marking) gets a strict-priority fast lane capped at 20% of the link. BULK-DATA (DSCP AF11) gets a guaranteed 40% minimum with WRED (covered separately) managing its queue. class-default, everything else, gets fair-queueing so no single flow can dominate the leftover bandwidth. And the policy is applied output, because queueing happens on egress, where the interface is the bottleneck.
Confirm it installed correctly:
R1#show policy-map interface Ethernet0/2
Class-map: EF-VOICE (match-all)
Match: dscp ef (46)
Priority: 20% (2000 kbps), burst bytes 50000, b/w exceed drops: 0
Class-map: BULK-DATA (match-all)
Match: dscp af11 (10)
bandwidth 40% (4000 kbps)
Class-map: class-default (match-any)
Fair-queue: per-flow queue limit 16 packetsCongest It and Watch the Priority Class Survive
Now the demonstration. First, a baseline: the voice flow (EF-marked UDP) on an uncongested link:
j@llmbits:~$ iperf3 -c 10.0.30.10 -u -b 1M -S 184 -t 5 # -S 184 = DSCP EF
[ 5] 0.00-5.05 sec 611 KBytes 992 Kbits/sec 0.110 ms 0/432 (0%) receiverClean: 0.11 ms jitter, 0% loss. Now saturate the same 5 Mbps link with a bulk transfer while the voice flow runs concurrently. The bulk transfer alone shows the link is genuinely full:
j@llmbits:~$ iperf3 -c 10.0.30.10 -t 12 -P 3 # bulk, best-effort
[SUM] 0.00-14.00 sec 14.8 MBytes 8.84 Mbits/sec 162 sender
[SUM] 0.00-16.25 sec 7.88 MBytes 4.07 Mbits/sec receiverThe sender pushed 8.84 Mbps into a 5 Mbps pipe; only 4.07 Mbps came out the far end, and there were 162 TCP retransmissions. That gap is real packet loss at the choke, real congestion, exactly the condition QoS exists for.
And here is the payoff, the priority class under that same congestion:
R1#show policy-map interface Ethernet0/2
Class-map: EF-VOICE (match-all)
1125 packets, 1673362 bytes
Priority: 20% (2000 kbps), burst bytes 50000, b/w exceed drops: 0
queue stats for all priority classes:
(queue depth/total drops/no-buffer drops) 0/0/0b/w exceed drops: 0. Total drops: 0. While the bulk transfer was losing 162 packets to congestion, the voice class in its strict-priority queue lost nothing. That is LLQ working: the priority queue is serviced first, so under congestion its packets go out ahead of the bulk, and the voice call stays clean while the file transfer takes the hit. The policer confirmed the EF traffic stayed under its 2000 kbps reservation, so none of it was dropped for exceeding.
That contrast, bulk losing 162 packets, voice losing zero, on the same congested link at the same moment, is the entire case for LLQ in one screen.
The CBWFQ Share
The bandwidth class earns its keep too. When the bulk traffic is marked into BULK-DATA (DSCP AF11), it lands in the CBWFQ class with its guaranteed 40% floor:
R1#show policy-map interface Ethernet0/2 | begin BULK-DATA
Class-map: BULK-DATA (match-all)
6767 packets, 10222250 bytes
Match: dscp af11 (10)
bandwidth 40% (4000 kbps)That 40% is a minimum guarantee under congestion, not a cap. If the link is otherwise idle, BULK-DATA can use more; the guarantee only kicks in when there is contention. This is the difference from policing (a hard ceiling): CBWFQ gives a floor and lets the class borrow above it when bandwidth is free.
Why the Percentages Must Add Up Carefully
A design rule that trips people up: the sum of your priority and bandwidth allocations cannot exceed the available bandwidth (by default, 75% of the interface, reserving headroom for control traffic and overhead). Here, 20% priority + 40% bandwidth = 60%, which is safe. Push it toward 100% and IOS will reject the policy or you will starve control-plane traffic.
And a voice-specific rule: keep the priority (LLQ) allocation modest, typically no more than about a third of the link. Voice does not need much bandwidth (a G.711 call is roughly 80 kbps), but it needs that little bit reliably and with low latency. Over-allocating the priority queue wastes bandwidth other classes could use and, worse, a huge strict-priority queue can delay everything else during a burst.
FAQ
What is the difference between priority and bandwidth?
priority (LLQ) is a strict-priority, policed fast lane for latency-sensitive traffic like voice. bandwidth (CBWFQ) is a guaranteed minimum share with no latency guarantee, for important data. Fast lane vs reserved minimum.
Why is the priority queue policed?
So it cannot starve other classes. A strict-priority queue is always serviced first; without a policer capping it, a flood of priority traffic could consume the entire link. The policer makes strict priority safe.
Does QoS do anything on an uncongested link?
No. Queueing only matters when packets must wait. On a link that is not full, everything leaves immediately and the policy has no effect. QoS is about behaviour under congestion.
Where do I apply the policy, input or output?
Output. Queueing happens on egress, where the interface is the bottleneck. You classify and mark on input at the edge, but you queue on output.
How much bandwidth should the priority class get?
Keep it modest, typically under a third of the link. Voice needs reliability and low latency, not much bandwidth. Over-allocating priority wastes capacity and can delay other traffic during bursts.
Key Takeaways
- Queueing only matters under congestion. To demonstrate it you must actually fill the link, which the lab did with a 5 Mbps choke.
- priority (LLQ) = strict-priority, policed fast lane for voice. bandwidth (CBWFQ) = guaranteed minimum share for important data. Different jobs.
- The LLQ priority queue is policed so it cannot starve other classes. That policer is what makes strict priority safe.
- The lab proved it: under congestion the bulk transfer lost 162 packets while the voice class lost zero (b/w exceed drops: 0), on the same link at the same time.
- CBWFQ's bandwidth is a minimum floor under contention, not a cap; the class can borrow more when the link is free.
- Priority + bandwidth allocations must fit within the reservable bandwidth (default 75%), and the priority share should stay modest.
Next: WRED and congestion avoidance, or the QoS cluster guide.