"The calls are bad" is the least actionable ticket in unified communications. Bad how? For whom? In which direction? Almost every VoIP quality investigation that drags on for weeks does so because nobody separated the symptoms before reaching for a solution.
This is the diagnostic order that finds the fault quickly.
Name the symptom precisely
Four distinct problems get reported identically. They have different causes and different fixes.
| Symptom | User describes it as | Usual cause |
|---|---|---|
| Choppy / robotic audio | "cutting out", "underwater" | Packet loss |
| Delay before the other person responds | "talking over each other" | Latency |
| Warbling, uneven speech | "wobbly", "vibrating" | Jitter |
| One-way audio | "they can't hear me" | NAT / SIP signalling |
One-way audio is not a quality problem at all — it is a signalling or NAT problem, and no amount of QoS will fix it. Separating it out immediately saves days.
The numbers that matter
Get MOS or the raw RTP statistics before theorising. Every platform exposes them.
On Asterisk:
asterisk -rx "sip show channelstats"
Peer Call ID Duration Recv: Pack Lost Pct Jitter Send: Pack Lost Pct Jitter
10.20.4.51 a1b2c3d4 00:04:12 12409 284 2.2% 31.4 12388 3 0.0% 4.1
The targets, and they are not negotiable:
| Metric | Good | Acceptable | Broken |
|---|---|---|---|
| One-way latency | < 100 ms | < 150 ms | > 200 ms |
| Jitter | < 15 ms | < 30 ms | > 50 ms |
| Packet loss | < 0.5% | < 1% | > 2% |
| MOS | > 4.0 | > 3.6 | < 3.2 |
In the sample above, receive loss is 2.2% with 31 ms jitter while send is clean. The problem is inbound to the PBX, on the path from the phone. That single asymmetry eliminates half the possible causes — it is not the trunk, and it is not the far end.
Always read both directions. Symmetric degradation points at a shared path — the internet link, the trunk. Asymmetric degradation points at one leg, and tells you which one to walk.
Work outward from the endpoint
Is it the local network?
Wireless is the first suspect and usually the correct one. Wi-Fi introduces jitter through retransmission and roaming, and a phone that roams between access points mid-call drops packets during the handoff.
# Sustained loss/jitter to the PBX — run for at least 5 minutes
mtr --report --report-cycles 300 --interval 1 pbx.internal.example
# Or a quick check against the media gateway
ping -i 0.2 -c 1500 10.20.0.30 | tail -3
If loss appears only on wireless clients, you have a Wi-Fi problem, not a VoIP problem. Check for co-channel interference, undersized channel width, and roaming thresholds. Enable WMM — without it, voice frames queue behind bulk traffic at the access point.
Is QoS actually applied?
Everyone configures QoS. Far fewer verify it survives the whole path. The most common failure is a switch that trusts DSCP on one port and rewrites it on another.
Capture at several points and compare the DSCP markings:
# RTP should carry DSCP EF (46). tos 0xb8 == DSCP 46.
tcpdump -i eth0 -n 'udp portrange 10000-20000' -v | grep -o 'tos 0x[0-9a-f]*' | sort | uniq -c
4821 tos 0xb8 <- correct, EF
193 tos 0x0 <- remarked to best effort somewhere upstream
Those 193 packets found a device that stripped the marking. On Cisco, verify the trust boundary explicitly:
show mls qos interface GigabitEthernet1/0/12
show policy-map interface GigabitEthernet1/0/12
The rule: trust DSCP at the access port where the phone connects, and nowhere the user can reach. A user's PC can mark its own traffic EF and starve the voice queue it is trying to join.
Is the WAN the bottleneck?
For calls that leave the building, the internet link is the usual constraint — and the usual culprit is bufferbloat rather than raw bandwidth.
A link that shows 200 Mbps on a speed test can still ruin calls if the router's queue fills during a large upload. Test latency under load:
# While a large upload runs, watch what happens to latency
ping -i 0.2 8.8.8.8
If idle latency is 12 ms and loaded latency is 300 ms, you have bufferbloat. Fix it with a fair-queuing discipline and a shaper set slightly below the true line rate:
# Linux edge router — cake with an 85% shaper
tc qdisc replace dev eth1 root cake bandwidth 180Mbit diffserv4 nat egress
On MikroTik, the equivalent is a queue tree with cake or a properly configured PCQ. The essential part is shaping below the provider's rate, so the queue you control is the one that fills — not the invisible one in the provider's equipment.
One-way audio: a signalling problem
One-way audio is almost always NAT. SIP carries IP addresses inside the message body, and a naive NAT translates the packet headers while leaving the SDP untouched. The far end then sends RTP to an unroutable private address.
INVITE sip:1000@pbx.example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.50:5060;branch=z9hG4bK-524287-1
Contact: <sip:2000@192.168.1.50:5060>
...
c=IN IP4 192.168.1.50 <- private address advertised to the internet
m=audio 16384 RTP/AVP 0 8 101
Fixes, in order of preference:
- A session border controller. Purpose-built, handles NAT traversal, topology hiding, and transcoding. The right answer for anything production.
externip/externaddron the PBX so it rewrites the SDP itself:
; pjsip.conf
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
external_media_address=203.0.113.40
external_signaling_address=203.0.113.40
local_net=10.20.0.0/16
local_net=192.168.0.0/16
- SIP ALG on the firewall. Listed for completeness, and it is nearly always wrong.
Disable SIP ALG. Firewall SIP ALG implementations rewrite packets in ways that break more calls than they fix — mangling headers, corrupting re-INVITEs, and breaking TLS-encrypted signalling entirely. On virtually every consumer and small-business firewall, turning it off is the fix. Check for it first; it wastes more engineer-hours than any other single setting.
Codec choice
Codec selection changes bandwidth and resilience, not just quality.
| Codec | Payload bandwidth | With overhead | Notes |
|---|---|---|---|
| G.711 | 64 kbps | ~87 kbps | Toll quality, no compression, high CPU efficiency |
| G.722 | 64 kbps | ~87 kbps | Wideband — noticeably better on good networks |
| G.729 | 8 kbps | ~31 kbps | Compressed, degrades sharply with loss |
| Opus | 6–128 kbps | Variable | Adaptive, best loss concealment |
Use G.711 on the LAN — bandwidth is free internally, and the CPU savings matter on a busy PBX. Use Opus across the WAN where it is supported; its adaptive bitrate and packet loss concealment handle bad networks far better than anything else on the list.
Avoid G.729 unless bandwidth is genuinely scarce. Its compression is unforgiving of loss, and transcoding between G.729 and G.711 at a gateway costs CPU and adds delay.
Never allow transcoding you did not intend. Two endpoints negotiating different codecs force the PBX to transcode every packet, which caps your concurrent call capacity far below what the hardware suggests.
The order I actually work in
- Classify the symptom. Choppy, delayed, warbling, or one-way. One-way goes straight to the NAT/SIP path.
- Pull RTP statistics in both directions. Note the asymmetry — it names the faulty leg.
- Check the endpoint's network. Wireless first, then the access switch port.
- Verify DSCP survives end to end with a capture at each hop.
- Test latency under load on the WAN link. Shape if it inflates.
- Check the trunk with the provider — ask for their RTP statistics for the same call ID.
- Review codec negotiation and confirm nothing is transcoding unexpectedly.
Steps 1 and 2 solve or localise the majority of cases in under fifteen minutes. The temptation is to skip to step 5 because the WAN is the usual suspect — resist it, because the fifteen minutes you save are paid back with interest when the answer turns out to be an access point.
0 comments
Sign in to join the discussion.
No comments yet. If something here is wrong or incomplete, say so — corrections are welcome.