Back to blog

Cisco / IOS  ·  Tutorial  ·  July 2026

Cisco IOS
QoS for VoIP

Voice is tiny but merciless: 100 kbps of RTP that turns to garbage the instant it waits behind someone's file upload. QoS gives those packets a fast lane — mark them at the phone, trust the mark, and put voice in a strict-priority queue so calls stay crystal clear even when the link is full.

Cisco IOS QoS VoIP DSCP LLQ MQC CCNP

CLASSIFY → QUEUE → SCHEDULE (out the WAN) voice RTP · EF signaling · CS3 web / bulk · default PRIORITY (LLQ) — served first signaling — bandwidth 5% default — the rest WAN link (congested) QoS only matters when the link is FULL — that's when the scheduler decides who waits. Voice never does.

A VoIP call is about 80–100 kbps of small UDP/RTP packets, and it has zero tolerance for delay or loss: 150 ms of latency or a 1% drop and callers start talking over each other. The killer isn't bandwidth — a call is tiny — it's queuing delay. When the link fills up (someone uploads to the cloud, a backup kicks off), voice packets sit in the same FIFO queue behind big data packets, and the call stutters. QoS is the fix: identify voice, and let it jump the queue.

Three moves do it. Classify & mark — tag voice packets with DSCP EF (Expedited Forwarding) so every device recognizes them. Trust the boundary — let the IP phone mark, and have the switch trust that mark rather than re-inspecting. Queue with priority — a Low-Latency Queue (LLQ) that services voice strictly first, with a policer so it can't starve everything else. It's all built with the same Modular QoS CLI (MQC) — class-maps and policy-maps — you met in the firewall post. This mirrors our MikroTik QoS writeup; the concepts are identical.

Prerequisites

01

Marking — Speak DSCP

Every packet's IP header has a DSCP field. Voice bearer traffic gets EF, call signaling gets CS3. Mark once, near the edge, and every downstream device can act on it without re-inspecting.

TrafficDSCPWhy
Voice bearer (RTP)EF (46)The audio itself — strict priority, lowest latency.
Call signaling (SIP/SCCP)CS3 (24)Sets up/tears down calls — important but not latency-critical.
Everything elseDefault (0)Best effort — web, email, file transfers.
💡 Mark at the Edge, Act in the Core

The golden rule of QoS: classify and mark as close to the source as possible, then trust that marking everywhere else. Re-classifying deep-packet-style at every hop is expensive and fragile; a consistent DSCP set once at the access edge lets every switch and router downstream make a cheap, instant decision. This only works if you also control who is allowed to set marks — which is the trust boundary, next.

02

The Trust Boundary

A Cisco IP phone marks its own RTP as EF — but an attached PC could mark its game or torrent EF too and steal the priority lane. The switch decides whose marks to believe. Trust the phone; re-mark the PC to zero.

IOS (access switch) — trust the phone, distrust the PC behind it
# Enable QoS globally (off by default on many Catalysts)
SW1(config)# mls qos

SW1(config)# interface GigabitEthernet0/5
SW1(config-if)# switchport access vlan 10       # data VLAN (the PC)
SW1(config-if)# switchport voice vlan 110       # voice VLAN (the phone)

# Trust the DSCP the phone sets — but only via the phone (CDP-verified):
SW1(config-if)# mls qos trust device cisco-phone
SW1(config-if)# mls qos trust dscp
# The PC hangs off the phone's switch port; the phone RE-MARKS the PC's
# traffic to DSCP 0, so a PC can't fake EF and jump the voice queue.
⚠ Gotcha — An Untrusted Port Erases Your Marks

With mls qos globally enabled, ports default to untrusted — they rewrite incoming DSCP to 0. So enabling QoS without setting trust can make voice worse: the phone marks EF, the switch wipes it to 0, and downstream LLQ never matches. Either extend the trust boundary correctly (trust the phone at the edge) or explicitly re-mark voice yourself with a policy. Verify with show mls qos interface gi0/5 — it tells you the trust state and whether marks survive.

03

Classify — Match the Voice

On the router that will queue, define classes that match the DSCP values the edge already set. Matching a trusted mark is cheap; matching by ACL/port is the fallback when you can't trust the source.

IOS (WAN router) — classes for voice and signaling
# Preferred: match the DSCP the edge already marked
R1(config)# class-map match-all VOICE
R1(config-cmap)# match dscp ef
R1(config-cmap)# exit
R1(config)# class-map match-any SIGNALING
R1(config-cmap)# match dscp cs3
R1(config-cmap)# match dscp af31
R1(config-cmap)# exit

# Fallback if you must classify by port instead of trusting a mark:
#   match ip rtp 16384 16383   ← the standard RTP UDP port range

04

LLQ — The Strict-Priority Queue

This is the heart of voice QoS. A Low-Latency Queue serves voice before everything else, every time — but with a bandwidth cap (a built-in policer) so a flood of voice can't starve the link. Everything else shares what's left by weight.

IOS — the policy-map: priority for voice, bandwidth for the rest
R1(config)# policy-map WAN-QOS
R1(config-pmap)# class VOICE
R1(config-pmap-c)# priority percent 20     # LLQ: strict priority, capped at 20%
R1(config-pmap-c)# exit
R1(config-pmap)# class SIGNALING
R1(config-pmap-c)# bandwidth percent 5      # guaranteed 5%, not strict-priority
R1(config-pmap-c)# exit
R1(config-pmap)# class class-default
R1(config-pmap-c)# fair-queue            # everyone else shares fairly
R1(config-pmap-c)# random-detect dscp-based # WRED: drop early, avoid TCP sync
R1(config-pmap-c)# end

# Attach it OUTBOUND on the WAN interface — QoS acts on egress congestion
R1(config)# interface GigabitEthernet0/0
R1(config-if)# service-policy output WAN-QOS
R1(config-if)# end
⚠ Gotcha — Don't Give Voice More Than ~33% of the Link

The priority queue is strict — it will happily starve everything else if you let it. The rule of thumb is to cap voice at no more than a third of the link (20–33%), sized to your real call count: roughly 100 kbps per G.711 call plus overhead. Over-provisioning the priority class means a burst of voice (or anything mismarked as EF) can choke data and even routing keepalives. The policer built into priority protects the rest of the link — but only if you set it sanely.

💡 On Slow Links, Shape First

QoS only engages when the interface queue fills. On a sub-line-rate WAN (a 50/10 Mbps service on a GigE handoff), the router's physical interface never looks "full," so the queue never forms and your policy never triggers — the ISP drops your packets instead, with no QoS. The fix is a parent shaper: shape average to your real contracted rate in an outer policy, with WAN-QOS nested inside it. This hierarchical (parent-shape, child-queue) policy is how QoS is done on nearly every real internet circuit — worth its own deep-dive.

05

Verify Under Load Safe to Run

QoS is invisible until the link is busy. The one command that matters shows per-class packet counts, drops, and — critically — whether the priority queue is dropping anything (it never should).

IOS — read the policy counters during congestion
R1# show policy-map interface GigabitEthernet0/0
 Class-map: VOICE (match-all)
   2841000 packets
   Priority: 20% (2000 kbps), burst 50000, b/w exceed drops: 0
                                              ↑ MUST be 0 — voice never dropped

 Class-map: SIGNALING (match-any)
   14200 packets   bandwidth 5% (500 kbps)

 Class-map: class-default
   8100000 packets
   queue limit 64 packets
   (drops) 24710                        ← data drops under load: EXPECTED & fine

# The whole point in one screen: voice "exceed drops: 0" while data drops
# during congestion. That's QoS working — the right traffic waits.
CommandAnswers
show policy-map interface g0/0Per-class counts and drops — the money command. Voice drops must be 0.
show mls qos interface g0/5Switch-side trust state — are the phone's marks surviving?
show policy-map WAN-QOSThe configured policy, as parsed.
show class-mapWhat each class matches.

06

MikroTik ↔ Cisco — Same Priorities

Our MikroTik QoS post solves the identical problem with queue trees and mangle marks. The DSCP values are universal; only the queuing engine differs.

MikroTik / RouterOSCisco IOS
mangle mark-packet by port/DSCPclass-map match dscp / match ip rtp
Set DSCP in mangle (change-dscp)set dscp ef in a policy-map
Queue tree, priority=1 for voiceLLQ priority percent 20
max-limit on the voice queueThe policer built into priority
Parent queue = link speedParent shape average (HQoS)
bridge port trust for phone marksmls qos trust device cisco-phone

Takeaways

  1. Voice fails on delay, not bandwidth. A call is tiny; the enemy is queuing delay when the link fills. QoS only matters during congestion — it decides who waits, and voice never should.
  2. Mark once at the edge, act everywhere. Voice bearer = DSCP EF, signaling = CS3. Consistent marks let every downstream device make a cheap, instant decision.
  3. The trust boundary is the security of QoS. Trust the phone's marks, re-mark the PC to 0 — or a torrent tagged EF steals the voice lane. An untrusted port silently wipes marks to 0.
  4. LLQ is the heart of it. priority serves voice strictly first, with a built-in policer so it can't starve the link. Cap it at ~20–33%, sized to real call count.
  5. Attach the policy outbound, on the congested (WAN) interface. QoS acts on egress; inbound shaping is a different, harder problem.
  6. On sub-rate circuits, shape first. If the physical interface never looks full, nest the queuing policy inside a parent shape average at your real contracted rate.
  7. Verify under load with one command. show policy-map interface — voice "exceed drops: 0" while data drops during congestion is QoS working exactly as designed.

VoIP breaking up when the office gets busy in Crete?

Voice and a guest downloading a movie do not share a link well without help. I design QoS with proper marking, trust boundaries at the edge, and priority queuing tuned to your actual call volume — not a generic template.

Book a Discovery Call →