Add troubleshooting article: Wi-Fi 160 MHz airtime saturation breaking game streaming
This commit is contained in:
parent
3f94ebb963
commit
27ea2dc62b
3 changed files with 116 additions and 0 deletions
|
|
@ -11,6 +11,7 @@ Practical fixes for common Linux, networking, and application problems.
|
|||
- [LoRA adapter — GGUF conversion fails with 'config.json not found'](gpu-display/lora-adapter-gguf-conversion-fails.md)
|
||||
|
||||
## 🌐 Networking & Web
|
||||
- [Wi-Fi Game Streaming Stutter: 160 MHz Channel Width Saturating the 5 GHz Radio](networking/wifi-160mhz-airtime-saturation-game-streaming.md)
|
||||
- [Apache Outage: Fail2ban Self-Ban + Missing iptables Rules](networking/fail2ban-self-ban-apache-outage.md)
|
||||
- [Mail Client Stops Receiving: Fail2ban IMAP Self-Ban](networking/fail2ban-imap-self-ban-mail-client.md)
|
||||
- [firewalld: Mail Ports Wiped After Reload](networking/firewalld-mail-ports-reset.md)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
---
|
||||
title: "Wi-Fi Game Streaming Stutter: 160 MHz Channel Width Saturating the 5 GHz Radio"
|
||||
domain: troubleshooting
|
||||
category: networking
|
||||
tags: [wifi, 5ghz, 160mhz, channel-width, dfs, steam-deck, game-streaming, asuswrt, airtime, chanim]
|
||||
status: published
|
||||
created: 2026-06-13
|
||||
updated: 2026-06-13
|
||||
---
|
||||
|
||||
# Wi-Fi Game Streaming Stutter: 160 MHz Channel Width Saturating the 5 GHz Radio
|
||||
|
||||
## 🛑 Problem
|
||||
|
||||
Streaming a game from a desktop (wired) to a Steam Deck over Wi-Fi was stuttering intermittently — fine for a while, then choppy, hard to reproduce on demand. Throughput tests "looked fine," which is exactly why it was hard to pin down: **game streaming fails on jitter and microbursts of contention, not on average bandwidth.**
|
||||
|
||||
The Wi-Fi was an Asus RT-AX82U (AsusWRT, stock firmware) with the 5 GHz radio set to **Auto channel at 160 MHz width**.
|
||||
|
||||
## 🔍 Diagnosis
|
||||
|
||||
The key insight: **signal was excellent, but latency was not.** That combination means the airwaves are busy, not weak.
|
||||
|
||||
### Step 1 — Measure jitter to the gateway from a Wi-Fi client
|
||||
|
||||
```bash
|
||||
ping -c 20 -i 0.2 192.168.50.1
|
||||
# round-trip min/avg/max/stddev = 7.5/27.0/61.0/16.5 ms
|
||||
```
|
||||
|
||||
27 ms **average** and 16 ms of jitter to your *own router* over Wi-Fi is pathological. A healthy 5 GHz link sits at 2–5 ms. Yet the client's signal was **-43 dBm** (excellent) with a clean **-92 dBm** noise floor. Strong signal + high jitter = **airtime contention**, not range or interference at the receiver.
|
||||
|
||||
### Step 2 — Confirm channel utilization at the router
|
||||
|
||||
AsusWRT/Broadcom exposes per-channel airtime stats via `wl chanim_stats`. SSH into the router and run it against the 5 GHz interface:
|
||||
|
||||
```bash
|
||||
# 5 GHz interface name varies (eth6/eth7); resolve it from nvram
|
||||
IF=$(nvram get wl1_ifname)
|
||||
wl -i "$IF" chanspec # e.g. 36/160 (0xe832) → channel 36, 160 MHz
|
||||
wl -i "$IF" assoclist | wc -l # number of associated 5 GHz clients
|
||||
wl -i "$IF" chanim_stats
|
||||
```
|
||||
|
||||
The smoking gun (`chanim_stats`, version 3):
|
||||
|
||||
```
|
||||
chanspec tx inbss obss nocat nopkt doze txop goodtx badtx glitch ... idle
|
||||
0xe832 92 2 1 2 1 0 4 8 81 2 14
|
||||
```
|
||||
|
||||
Read it as percentages of airtime:
|
||||
|
||||
| Field | Value | Meaning |
|
||||
|-------|-------|---------|
|
||||
| `tx` | **92** | Channel busy transmitting 92% of the time |
|
||||
| `txop` | **4** | Transmit-opportunities available only 4% — the channel is starved |
|
||||
| `idle` | **14** | Channel idle only 14% |
|
||||
| `goodtx` / `badtx` | 8 / **81** | Failed/retried transmits vastly outnumber good ones |
|
||||
|
||||
Seventeen clients were associated to that one 5 GHz radio.
|
||||
|
||||
### Step 3 — Understand why 160 MHz makes it worse
|
||||
|
||||
A 160 MHz channel on the lower 5 GHz band spans channels **36–64**, which overlaps DFS sub-blocks. To stay clean it needs 160 MHz of *uncontended* spectrum — but in a dense RF environment (≈25 neighbor APs here, several on 5 GHz channels 48/52/100/132/153 that overlap or border the block), any one busy neighbor degrades the **entire** wide channel. 160 MHz also makes the radio **DFS-radar exposed**: a single radar detection forces a channel-switch with a 1 s+ blackout — a stream-killer.
|
||||
|
||||
So 160 MHz buys a higher *peak* PHY rate that game streaming doesn't need, at the cost of the *stability* it absolutely does.
|
||||
|
||||
## ✅ Fix
|
||||
|
||||
Drop the 5 GHz radio to **80 MHz** and pin it to a **non-DFS** channel (UNII-1: 36/40/44/48 — no radar, no DFS blackouts).
|
||||
|
||||
GUI: **Wireless → 5 GHz → Channel Bandwidth = 80 MHz**, **Control Channel = 36**, turn off "Auto."
|
||||
|
||||
Or over SSH (`nvram` + `restart_wireless`):
|
||||
|
||||
```bash
|
||||
nvram set wl1_bw_cap=7 # cap at 80 MHz (bitmask: 1=20, 3=40, 7=80, 15=160)
|
||||
nvram set wl1_chanspec=36/80 # channel 36 @ 80 MHz
|
||||
nvram set wl1_channel=36
|
||||
nvram commit
|
||||
service restart_wireless # ~15-20s radio bounce, drops all clients briefly
|
||||
```
|
||||
|
||||
> [!warning] `restart_wireless` drops every Wi-Fi client for 15–20 seconds. `nvram commit` runs *before* the restart, so the config persists even if your own SSH/Wi-Fi session drops.
|
||||
|
||||
## 📊 Result
|
||||
|
||||
Verified from both the router and a client after the radio came back:
|
||||
|
||||
| Metric | Before (36/160) | After (36/80) |
|
||||
|--------|-----------------|---------------|
|
||||
| Channel tx-busy | 92% | **9%** |
|
||||
| Transmit-opportunity available | 4% | **79%** |
|
||||
| Channel idle | 14% | **87%** |
|
||||
| Failed tx (`badtx` vs `goodtx`) | 81 vs 8 | **1 vs 3** |
|
||||
| Gateway ping (avg / floor) | 27 ms / 7.5 ms | **9 ms / 2.7 ms** |
|
||||
| PHY peak rate | 1729 Mbps | 1200 Mbps |
|
||||
|
||||
The PHY peak dropped (narrower channel) but that is irrelevant — Steam Remote Play wants ~30–50 Mbps with *consistent* airtime, which it now has. The stutter resolved.
|
||||
|
||||
## 🧠 Takeaways
|
||||
|
||||
- **Diagnose Wi-Fi streaming problems with jitter, not throughput.** A speed test can pass while a stream stutters. Ping your gateway and watch the stddev.
|
||||
- **Strong signal + high latency = airtime congestion.** Don't chase signal strength when RSSI is already good; look at channel utilization (`chanim_stats`).
|
||||
- **160 MHz is a trap in a dense RF environment.** Use 80 MHz for reliability; reserve 160 MHz for clean spectrum and short range.
|
||||
- **Prefer non-DFS channels (36–48) for anything latency-sensitive** — DFS radar events cause silent multi-second dropouts.
|
||||
- **Wire the *source*.** The streaming PC should be on Ethernet so the video only crosses the air once (AP → handheld). The handheld has to be Wi-Fi; the desktop doesn't.
|
||||
- **Isolate IoT on 2.4 GHz** (separate SSID) so it never competes for 5 GHz airtime with latency-sensitive clients.
|
||||
|
||||
## Related
|
||||
|
||||
- [Network Overview](../../02-selfhosting/dns-networking/network-overview.md)
|
||||
- [Wake-on-LAN via Router SSH](../../02-selfhosting/dns-networking/wake-on-lan-router-ssh.md)
|
||||
- [Pi-hole v6 Group Management — Per-Client DNS Rules](../../02-selfhosting/dns-networking/pihole-v6-group-management.md)
|
||||
|
|
@ -77,6 +77,7 @@ updated: 2026-05-15T09:00
|
|||
* [HEVC Batch Re-Encode for Plex Using VAAPI (AMD GPU)](04-streaming/plex/hevc-vaapi-batch-encode.md)
|
||||
* [Plex Transcoding Troubleshooting](04-streaming/plex/plex-transcoding-troubleshooting.md)
|
||||
* [Troubleshooting](05-troubleshooting/index.md)
|
||||
* [Wi-Fi Game Streaming Stutter: 160 MHz Channel Width Saturating the 5 GHz Radio](05-troubleshooting/networking/wifi-160mhz-airtime-saturation-game-streaming.md)
|
||||
* [Apache Outage: Fail2ban Self-Ban + Missing iptables Rules](05-troubleshooting/networking/fail2ban-self-ban-apache-outage.md)
|
||||
* [Postfix + SendGrid: TLS Handshake Failure (Port 465 vs 587)](05-troubleshooting/networking/postfix-sendgrid-tls-handshake-failure.md)
|
||||
* [Mail Client Stops Receiving: Fail2ban IMAP Self-Ban](05-troubleshooting/networking/fail2ban-imap-self-ban-mail-client.md)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue