QoS on a router is where quality of service stops being theory and becomes a config you actually type. The classification, marking, and queueing concepts are the same whether you are on a Catalyst 9500 or a branch ISR, but the router is where the WAN bottleneck lives, and the WAN bottleneck is where QoS earns its keep. This post is the practical version: how to build a working QoS policy on a Cisco router, what each piece does, and how to confirm it is doing something.
For the full picture, see the QoS complete guide.
Why the router is where QoS matters
Inside the LAN, bandwidth is cheap. Switch ports are 1 Gbps minimum, often 10 Gbps, and congestion is rare. QoS on a LAN switch mostly means "trust the markings and have sane queues."
The router's WAN interface is the opposite. It is the slow link. A branch with a 50 Mbps internet circuit and a gigabit LAN has a 20-to-1 speed mismatch at the router. When the LAN sends more than 50 Mbps toward the WAN, packets queue up inside the router, and the router decides who waits and who goes first. That decision is QoS. Without it, a large file upload and a voice call compete equally, and the voice call loses.
The MQC: three commands, one model
Cisco IOS XE QoS is built on the Modular QoS CLI (MQC). Every QoS policy, however complex, is three building blocks:
| Block | Command | What it does |
|---|---|---|
| Class map | class-map | Identifies traffic. "What is this packet?" |
| Policy map | policy-map | Decides what to do with each class. "How do I treat it?" |
| Service policy | service-policy | Applies the policy to an interface, in a direction. |
Class map answers what, policy map answers how, service policy answers where. Learn this and every QoS config you ever read decomposes cleanly.
Step 1: Classify with class maps
A class map matches traffic. You can match on DSCP markings (if the LAN already marked the traffic), on access lists, on protocols via NBAR, or on other criteria.
class-map match-any VOICE
match dscp ef
class-map match-any VIDEO
match dscp af41
class-map match-any CRITICAL-DATA
match dscp af31
match dscp cs3
class-map match-any SCAVENGER
match dscp cs1This assumes the LAN switches already marked the traffic (the normal design: mark at the access edge, trust at the router). If your endpoints do not mark, the router can classify with NBAR instead:
class-map match-any VOICE
match protocol rtp audioNBAR is heavier on the CPU but works when you cannot trust upstream markings. Most production designs mark at the access switch and let the router trust DSCP.
Step 2: Define treatment with a policy map
The policy map says what happens to each class. The two main tools are a priority queue (for voice) and bandwidth guarantees (for everything else).
policy-map WAN-QOS
class VOICE
priority percent 20
class VIDEO
bandwidth percent 25
class CRITICAL-DATA
bandwidth percent 25
class SCAVENGER
bandwidth percent 5
class class-default
bandwidth percent 25
random-detect dscp-basedReading this policy:
- VOICE gets
priority- a strict low-latency queue (LLQ). Voice packets jump ahead of everything else. Thepercent 20also polices it: voice cannot exceed 20% of the link even with priority, so a flood of EF-marked traffic cannot starve the rest. - VIDEO, CRITICAL-DATA, SCAVENGER, class-default get
bandwidth- a minimum guarantee during congestion via CBWFQ (Class-Based Weighted Fair Queueing). When the link is not congested, any class can use more than its guarantee. The guarantee only kicks in when there is contention. - class-default gets WRED (
random-detect) - drops packets early and randomly as the queue fills, which prevents TCP global synchronization (every flow backing off and ramping up in lockstep).
Step 3: Shape, then apply
Here is the part people miss. The policy map above only does something when the interface is congested. On a physical interface that runs below line rate, the queues never fill, and QoS never engages.
If your WAN circuit is a 50 Mbps service delivered over a physical gigabit handoff (extremely common with metro-ethernet and broadband), the router thinks the interface is 1 Gbps. It will happily send 1 Gbps until the provider drops the excess - and the provider drops without QoS awareness, so your voice packets die in the carrier's queue, not yours.
The fix is a hierarchical policy: a parent policy shapes traffic down to the real circuit rate, and the child policy (the one above) runs inside that shaped envelope.
policy-map WAN-PARENT
class class-default
shape average 50000000
service-policy WAN-QOS
!
interface GigabitEthernet0/0/0
description WAN - 50 Mbps circuit on a 1G handoff
service-policy output WAN-PARENTNow the router shapes its own output to 50 Mbps. Because it is now the bottleneck, its queues fill, and the child policy's priority queue and bandwidth guarantees actually take effect. Shape to the real rate, then queue inside it. This is the single most important QoS design rule on a router.
QoS direction: output is where the action is
QoS is applied per-interface, per-direction. On a router WAN interface, output (egress) is where queueing happens, because queueing only makes sense when packets are leaving toward a slower link.
You can apply policies inbound too, but inbound QoS is limited - you cannot queue traffic that has already arrived. Inbound policies are used for marking (set DSCP on ingress) or policing (drop/remark traffic that exceeds a rate on the way in). The classic split: mark or police inbound, queue outbound.
Verifying it works
The command that tells you whether QoS is doing anything:
Router# show policy-map interface GigabitEthernet0/0/0
GigabitEthernet0/0/0
Service-policy output: WAN-PARENT
Class-map: class-default (match-any)
8204531 packets
Service-policy : WAN-QOS
Class-map: VOICE (match-any)
412904 packets
Match: dscp ef (46)
Priority: 20% (10000 kbps), burst bytes 250000
Priority Level 1:
412904 packets
drop rate 0 bps
Class-map: VIDEO (match-any)
88122 packets
Match: dscp af41 (34)
Queueing
bandwidth 25% (12500 kbps)
(total drops) 1208
(queue depth) 14What to read:
- VOICE drop rate. Should be 0. Any drops in the priority queue means voice is being lost - either you under-sized the priority percent or something is mismarked as EF.
- VIDEO total drops. Some drops here are normal during congestion - that is the bandwidth guarantee working. A flood of drops means the class is undersized.
- Packet counts climbing. If a class shows 0 packets, your classification is wrong - the traffic is not matching the class map. This is the most common QoS bug.
A note on home and SMB routers
The same model scales down. A small-business router (or a prosumer box running a real OS) does QoS the same way: classify, prioritize voice and video, shape to the actual circuit rate. The single highest-value QoS change on a home or SMB router is the shaper - set it to about 90-95% of your measured circuit speed so the router, not the ISP, is the bottleneck. That one setting is what stops a big upload from wrecking a video call.
Common mistakes
| Mistake | Symptom |
|---|---|
| No shaper on a sub-rate circuit | QoS configured but never engages; voice still choppy under load |
| Policy applied inbound expecting queueing | No effect; queueing only works outbound |
| Class map matches nothing | show policy-map interface shows 0 packets in the class |
| Priority percent too high | Non-voice classes starve; bulk traffic times out |
| Trusting markings from an untrusted source | Endpoints mark their own traffic EF and jump the queue |
Key takeaways
QoS on a router is three MQC blocks: a class map to identify traffic, a policy map to treat it, a service policy to apply it. Voice gets a strict priority queue; everything else gets bandwidth guarantees. The rule that makes or breaks the whole thing is the shaper: on any circuit slower than the physical interface, shape to the real rate so the router becomes the bottleneck and its queues actually engage. Verify with show policy-map interface and watch the drop counters.
For the full QoS cluster, see the QoS pillar.