I can repeatedly fix/break this issue now on every Mac I have. I hope several of you try this and report back. Good news is, it’s not hardware!
tl;dr
Ultimate Fix: Change your AP to use channel 6 for 2.4Ghz and 149 for 5Ghz. Sounds ridiculous, if you don't read the rest.
-----
Apple uses a virtual interface for AirDrop/AirPlay/Sidecar called "awdl0" that passes traffic through the active physical interface (en0). AWDL scans on channel 6 for 2.4Ghz and 149 for 5Ghz (or 44 in Europe/UK). If your WiFi AP isn't running on those channels, your Mac is briefly switching to those and back (Why Apple is strictly using those channels, is beyond me…).
If you are unable to change the WiFi AP channels (work, school, business, etc)… Then you can do the following “work-around” with caveats:
- Open a terminal session, then run these commands:
sudo ifconfig awdl0 up
sudo ifconfig awdl0 down
ping x.x.x.x (Gateway IP will work).
Monitor the pings. You should now see they have much lower latency and are stable. That, and overall network activity is drastically improved. Browsing, file sharing, streaming, remote sessions, VPN stays connected, etc...
It's important to up/down awdl0 each time. If MacOS re-enables the interface after it's been manually disabled, it may not stick otherwise.
Caveats:
- MacOS monitors awdl0 and will re-enable it every few minutes if it’s inactive. You’ll need to setup a cron job using perl/python (baseline scripts below) to monitor and maintain a down state. Be cautious using “sudo ifconfig awdl0 delete” instead, if it even allows it.
- You will lose AirDrop/AirPlay/Sidecar functionality, again this is a “work-around” if you can't change the AP channels to 6/149.
Sources:
https://mjtsai.com/blog/2022/12/19/disabling-awdl-to-work-around-ventura-wi-fi-issues/
https://forums.macrumors.com/threads/wi-fi-jitter-erratic-ping-latency-due-to-awdl-airdrop-airplay.2373916/
https://apple.stackexchange.com/questions/451646/force-disabling-awdl-on-ventura-or-above/454060
Perl:
#!/usr/bin/perl
use strict;
use warnings;
# The name of the interface to monitor
my $interface = "awdl0";
# Run the command to get the status of the interface
my $status = `ifconfig $interface`;
# Check if the interface is active
if ($status =~ /status: active/i) {
print "The $interface interface is active. Disabling...\n";
# Run the commands to disable the interface
system("sudo ifconfig $interface up");
system("sudo ifconfig $interface down");
} else {
print "The $interface interface is not active.\n";
}
Python:
#!/usr/bin/env python3
import subprocess
# The name of the interface to monitor
interface = "awdl0"
# Run the command to get the status of the interface
status_cmd = f"ifconfig {interface}"
status = subprocess.check_output(status_cmd, shell=True).decode()
# Check if the interface is active
if "status: active" in status:
print(f"The {interface} interface is active. Disabling...")
# Run the command to disable the interface
enable_cmd = f"sudo ifconfig {interface} up"
disable_cmd = f"sudo ifconfig {interface} down"
subprocess.check_output(enable_cmd, shell=True)
subprocess.check_output(disable_cmd, shell=True)
else:
print(f"The {interface} interface is not active.")