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?

NOCTIS designs QoS for hotels and SMBs running voice over the same link as everything else — proper marking, trust boundaries, and priority queuing tuned to your call volume. On Cisco or MikroTik, verified under real load.

Book a Discovery Call →