Skip to content
Development
Skill

/unifi-wifi

Use when UniFi Wi-Fi is slow, unstable, or being tuned: "my wifi is slow but speedtest on the router is fast", "great signal, terrible speed", "should I use 80MHz or 40MHz", "channel planning", "co-channel interference", "DFS channels", "my APs keep picking the same channel",

From plugin
unifi
455 skills

Claude Code

$ npx -y skills add t3chnaztea/unifi-skills --skill unifi-wifi --agent claude-code

SKILL.md

unifi-wifi.SKILL.md
name: unifi-wifi
description: >-
  Use when UniFi Wi-Fi is slow, unstable, or being tuned: "my wifi is slow but
  speedtest on the router is fast", "great signal, terrible speed", "should I
  use 80MHz or 40MHz", "channel planning", "co-channel interference", "DFS
  channels", "my APs keep picking the same channel", "audit my SSIDs", "hidden
  SSID", or diagnosing throughput that collapses under load. Also roaming: "my
  phone stays stuck on the far AP", "sticky clients", "improve roaming", "should
  I enable fast roaming", "minimum RSSI", "TX power tuning". Covers the
  diagnostic ladder for slow Wi-Fi, channel width and DFS tradeoffs, safe radio
  writes, cell sizing and roaming persuasion, SSID hygiene, and the in-wall AP
  port trap. Assumes unifi-connect.
  Not for firewall policy between networks (unifi-firewall), wired port and
  client operations (unifi-clients).
compatibility: >-
  UniFi Network with adopted UniFi APs. Channel and DFS specifics below are US
  regulatory domain. Verified on Network 10.4.57 with AC and WiFi 6 hardware.

UniFi Wi-Fi

Most "slow Wi-Fi" is not slow Wi-Fi. It is a WAN problem, a backhaul problem, a client problem, or a bandwidth cap somebody set two years ago. The diagnostic ladder below exists to find that out cheaply, in that order, before touching radios. Radio changes are the most disruptive and the most often wrong.

The diagnostic ladder

Run it top to bottom. Each rung eliminates a layer, and the failure that motivated this skill was only visible at the last rung.

**1. Rule out the WAN.** Trigger a gateway-side speedtest, which measures the gateway to the internet with no Wi-Fi involved:

udm raw POST /proxy/network/api/s/default/cmd/devmgr '{"cmd":"speedtest"}'
# wait, then read the RESULT from stat/device, not stat/health
udm devices --json | python3 -c '
import json,sys
for d in json.load(sys.stdin):
    s = d.get("speedtest-status")
    if s: print(d.get("name"), s.get("xput_download"), s.get("xput_upload"),
                "status_summary=", s.get("status_summary"))'

The result lands on the **gateway's** device object, under the hyphenated key `speedtest-status` (not `speedtest_status`), with throughput in the nested `xput_download` and `xput_upload` fields. `status_summary` tells you whether the run finished; a fresh gateway that has never run one reports zeros. `stat/health` is a different number entirely and will send you in circles.

**2. Check the AP's uplink.** An AP on a 100 Mbps link, or meshed rather than wired, caps every client behind it:

udm devices --json | python3 -c '
import json,sys
for d in json.load(sys.stdin):
    up = d.get("uplink") or {}
    print(d.get("name"), d.get("type"), up.get("speed"), up.get("type"))'

**3. Check the client's own view.** Signal, negotiated rate, satisfaction:

udm clients --json | python3 -c '
import json,sys
for c in json.load(sys.stdin):
    print(c.get("hostname"), c.get("signal"), c.get("tx_rate"), c.get("satisfaction"))'

This rung is where the interesting case appears. A client at **-57 dBm with an 866 Mbps PHY rate** has an excellent link. If it measures 32 Mbps, the radio is fine and something is contending. Signal is not throughput, and confusing the two is why people replace working access points.

**4. Rule out a bandwidth cap.** Somebody, possibly you, may have set one:

udm raw GET /proxy/network/api/s/default/rest/usergroup
udm wlans --json    # check per-SSID rate limits

**5. Compare every AP's channel, width, and channel utilization.** The last rung, and the one that finds co-channel contention:

udm devices --json | python3 -c '
import json,sys
for d in json.load(sys.stdin):
    for r in d.get("radio_table_stats") or []:
        print(d.get("name"), r.get("radio"), "ch", r.get("channel"),
              "bw", r.get("bw"), "cu_total", r.get("cu_total"),
              "sat", r.get("satisfaction"))'

Field names matter here and are not the obvious ones. Channel width is **`bw`**, not `channel_width`. The names are per object, not global: on a *client* record the same value really is `channel_width`. Check the object you are reading rather than carrying a field name across from another endpoint. `cu_total` is **channel utilization**, the percentage of airtime in use, and it is the closest thing to a direct measurement of the problem this skill is about. `cu_self_tx` and `cu_self_rx` break out how much of that is this AP's own traffic: **high `cu_total` with low `cu_self_*` means somebody else is using your airtime**, which is either a neighbor or, more often, your own AP two rooms away on the same channel.

`satisfaction` reports `-1` when a radio has no clients on it. That is "no data", not "terrible".

Read `radio_table_stats`, the operational state, not `radio_table`, the config. They disagree more often than you would like.

The 80 MHz trap

The failure that motivated this skill, because it is a change that looks free.

Setting every 5 GHz radio to 80 MHz doubles the theoretical per-client rate, so it reads like a pure upgrade. It is not, because **width is bought with channels.** In the US regulatory domain, 80 MHz with DFS channels disabled leaves exactly **two** non-overlapping blocks:

  • UNII-1: channels 36 / 40 / 44 / 48
  • UNII-3: channels 149 / 153 / 157 / 161

Two blocks. If you have more than two 5 GHz APs with overlapping coverage, some of them are sharing an 80 MHz block and taking turns transmitting. Wi-Fi degrades gracefully in signal terms and catastrophically in contention terms: everything looks healthy right up until two clients are busy simultaneously.

The observed case: four APs, three of them in-wall units on adjacent walls, all piled into UNII-1 after a global switch to 80 MHz. Result was roughly **32 Mbps on a gigabit connection**, with an 866 Mbps PHY link at -57 dBm and a confirmed 1276 Mbps gateway speedtest. Neither ISP, backhaul, nor signal was the cap.

**Do not disable

Read more
@t3chnaztea
Ships withunifi

Agent skills for administering a real UniFi network over its local API: auth, zone firewall, Wi-Fi, clients, and the site map.

Stars on GitHub

Momentum

stars in total
45
Star history of t3chnaztea/unifi-skills on GitHub, a chart by star-history.com

Other skills on unifi.

unifi-clients

unifi-clients

Use when operating on UniFi clients, devices, switch ports, or DHCP: "block a device", "kick a client off wifi", "restart an…

@t3chnaztea@t3chnazteaInstall Skill
unifi-connect

unifi-connect

Use when connecting an agent to a UniFi gateway (UDM Pro, UDM SE, Cloud Gateway) for the first time, or when API calls to one are…

@t3chnaztea@t3chnazteaInstall Skill
unifi-context-map

unifi-context-map

Use when an agent keeps guessing wrong about a UniFi network, when starting recurring agent work against a gateway, or when asked…

@t3chnaztea@t3chnazteaInstall Skill
unifi-firewall

unifi-firewall

Use when working on UniFi firewall rules, zones, or network segmentation: "my firewall rules are empty", "rest/firewallrule…

@t3chnaztea@t3chnazteaInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about unifi-wifi.

Which coding agents can use unifi-wifi?
unifi-wifi installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.