Latency spikes with Apple/Mac WiFi

This is more of a PSA as opposed to a question. Though, I do hope this drums up some good conversation and maybe solutions.

For users of Apple devices that connect wirelessly, if you perform a constant ping to some host (another LAN host is fine) you will likely notice some latency spikes at a fairly consistent interval. The exact interval is going to differ based on some factors I will point out in a moment.

Here is an example of what you would see when pinging a LAN host from your Apple device at an interval of 0.1. Take special note of timestamp 15:13:55.887877 and notice the behavior for the 4 seconds or so following that timestamp:

Summary
ping -i.1 192.168.45.15 --apple-time
...
15:13:43.946954 64 bytes from 192.168.45.15: icmp_seq=18526 ttl=64 time=4.338 ms
15:13:44.050929 64 bytes from 192.168.45.15: icmp_seq=18527 ttl=64 time=3.137 ms
15:13:44.156021 64 bytes from 192.168.45.15: icmp_seq=18528 ttl=64 time=5.523 ms
15:13:44.253416 64 bytes from 192.168.45.15: icmp_seq=18529 ttl=64 time=1.992 ms
15:13:44.360483 64 bytes from 192.168.45.15: icmp_seq=18530 ttl=64 time=3.916 ms
15:13:44.462372 64 bytes from 192.168.45.15: icmp_seq=18531 ttl=64 time=2.933 ms
15:13:44.567400 64 bytes from 192.168.45.15: icmp_seq=18532 ttl=64 time=2.785 ms
15:13:44.669981 64 bytes from 192.168.45.15: icmp_seq=18533 ttl=64 time=2.812 ms
15:13:44.776374 64 bytes from 192.168.45.15: icmp_seq=18534 ttl=64 time=4.071 ms
15:13:44.876172 64 bytes from 192.168.45.15: icmp_seq=18535 ttl=64 time=2.955 ms
15:13:44.981494 64 bytes from 192.168.45.15: icmp_seq=18536 ttl=64 time=3.139 ms
15:13:45.081834 64 bytes from 192.168.45.15: icmp_seq=18537 ttl=64 time=3.247 ms
15:13:45.184425 64 bytes from 192.168.45.15: icmp_seq=18538 ttl=64 time=2.771 ms
15:13:45.286442 64 bytes from 192.168.45.15: icmp_seq=18539 ttl=64 time=3.075 ms
15:13:45.388422 64 bytes from 192.168.45.15: icmp_seq=18540 ttl=64 time=2.571 ms
15:13:45.493805 64 bytes from 192.168.45.15: icmp_seq=18541 ttl=64 time=3.885 ms
15:13:45.593671 64 bytes from 192.168.45.15: icmp_seq=18542 ttl=64 time=3.483 ms
15:13:45.694027 64 bytes from 192.168.45.15: icmp_seq=18543 ttl=64 time=3.725 ms
15:13:45.798109 64 bytes from 192.168.45.15: icmp_seq=18544 ttl=64 time=2.673 ms
15:13:45.902458 64 bytes from 192.168.45.15: icmp_seq=18545 ttl=64 time=4.552 ms
15:13:46.003394 64 bytes from 192.168.45.15: icmp_seq=18546 ttl=64 time=2.852 ms
15:13:46.108812 64 bytes from 192.168.45.15: icmp_seq=18547 ttl=64 time=3.129 ms
15:13:46.209691 64 bytes from 192.168.45.15: icmp_seq=18548 ttl=64 time=3.045 ms
15:13:46.309742 64 bytes from 192.168.45.15: icmp_seq=18549 ttl=64 time=2.856 ms
15:13:46.415094 64 bytes from 192.168.45.15: icmp_seq=18550 ttl=64 time=3.071 ms
15:13:46.520749 64 bytes from 192.168.45.15: icmp_seq=18551 ttl=64 time=3.554 ms
15:13:46.620777 64 bytes from 192.168.45.15: icmp_seq=18552 ttl=64 time=3.129 ms
15:13:46.723498 64 bytes from 192.168.45.15: icmp_seq=18553 ttl=64 time=2.899 ms
15:13:46.826668 64 bytes from 192.168.45.15: icmp_seq=18554 ttl=64 time=3.388 ms
15:13:46.927590 64 bytes from 192.168.45.15: icmp_seq=18555 ttl=64 time=4.020 ms
15:13:47.031927 64 bytes from 192.168.45.15: icmp_seq=18556 ttl=64 time=3.232 ms
15:13:47.137032 64 bytes from 192.168.45.15: icmp_seq=18557 ttl=64 time=3.463 ms
15:13:47.237496 64 bytes from 192.168.45.15: icmp_seq=18558 ttl=64 time=3.554 ms
15:13:47.342707 64 bytes from 192.168.45.15: icmp_seq=18559 ttl=64 time=3.632 ms
15:13:47.446623 64 bytes from 192.168.45.15: icmp_seq=18560 ttl=64 time=6.665 ms
15:13:47.546519 64 bytes from 192.168.45.15: icmp_seq=18561 ttl=64 time=2.930 ms
15:13:47.647798 64 bytes from 192.168.45.15: icmp_seq=18562 ttl=64 time=4.035 ms
15:13:47.752697 64 bytes from 192.168.45.15: icmp_seq=18563 ttl=64 time=3.751 ms
15:13:47.853448 64 bytes from 192.168.45.15: icmp_seq=18564 ttl=64 time=3.334 ms
15:13:47.953861 64 bytes from 192.168.45.15: icmp_seq=18565 ttl=64 time=3.306 ms
15:13:48.058522 64 bytes from 192.168.45.15: icmp_seq=18566 ttl=64 time=2.889 ms
15:13:48.159924 64 bytes from 192.168.45.15: icmp_seq=18567 ttl=64 time=3.231 ms
15:13:48.265052 64 bytes from 192.168.45.15: icmp_seq=18568 ttl=64 time=4.185 ms
15:13:48.368632 64 bytes from 192.168.45.15: icmp_seq=18569 ttl=64 time=2.652 ms
15:13:48.471464 64 bytes from 192.168.45.15: icmp_seq=18570 ttl=64 time=4.240 ms
15:13:48.575640 64 bytes from 192.168.45.15: icmp_seq=18571 ttl=64 time=3.541 ms
15:13:48.677461 64 bytes from 192.168.45.15: icmp_seq=18572 ttl=64 time=4.149 ms
15:13:48.776163 64 bytes from 192.168.45.15: icmp_seq=18573 ttl=64 time=2.815 ms
15:13:48.879925 64 bytes from 192.168.45.15: icmp_seq=18574 ttl=64 time=5.750 ms
15:13:48.982526 64 bytes from 192.168.45.15: icmp_seq=18575 ttl=64 time=3.192 ms
15:13:49.088516 64 bytes from 192.168.45.15: icmp_seq=18576 ttl=64 time=4.608 ms
15:13:49.188092 64 bytes from 192.168.45.15: icmp_seq=18577 ttl=64 time=3.048 ms
15:13:49.293209 64 bytes from 192.168.45.15: icmp_seq=18578 ttl=64 time=3.204 ms
15:13:49.399979 64 bytes from 192.168.45.15: icmp_seq=18579 ttl=64 time=9.702 ms
15:13:49.497965 64 bytes from 192.168.45.15: icmp_seq=18580 ttl=64 time=4.569 ms
15:13:49.600145 64 bytes from 192.168.45.15: icmp_seq=18581 ttl=64 time=3.559 ms
15:13:49.703591 64 bytes from 192.168.45.15: icmp_seq=18582 ttl=64 time=2.978 ms
15:13:49.806710 64 bytes from 192.168.45.15: icmp_seq=18583 ttl=64 time=3.571 ms
15:13:49.911597 64 bytes from 192.168.45.15: icmp_seq=18584 ttl=64 time=4.957 ms
15:13:50.014580 64 bytes from 192.168.45.15: icmp_seq=18585 ttl=64 time=2.757 ms
15:13:50.119493 64 bytes from 192.168.45.15: icmp_seq=18586 ttl=64 time=2.733 ms
15:13:50.220695 64 bytes from 192.168.45.15: icmp_seq=18587 ttl=64 time=3.411 ms
15:13:50.326338 64 bytes from 192.168.45.15: icmp_seq=18588 ttl=64 time=4.000 ms
15:13:50.425947 64 bytes from 192.168.45.15: icmp_seq=18589 ttl=64 time=2.590 ms
15:13:50.526661 64 bytes from 192.168.45.15: icmp_seq=18590 ttl=64 time=3.031 ms
15:13:50.631585 64 bytes from 192.168.45.15: icmp_seq=18591 ttl=64 time=2.822 ms
15:13:50.734953 64 bytes from 192.168.45.15: icmp_seq=18592 ttl=64 time=3.887 ms
15:13:50.837823 64 bytes from 192.168.45.15: icmp_seq=18593 ttl=64 time=3.896 ms
15:13:50.942164 64 bytes from 192.168.45.15: icmp_seq=18594 ttl=64 time=3.098 ms
15:13:51.043113 64 bytes from 192.168.45.15: icmp_seq=18595 ttl=64 time=3.035 ms
15:13:51.152068 64 bytes from 192.168.45.15: icmp_seq=18596 ttl=64 time=9.906 ms
15:13:51.244084 64 bytes from 192.168.45.15: icmp_seq=18597 ttl=64 time=1.670 ms
15:13:51.350855 64 bytes from 192.168.45.15: icmp_seq=18598 ttl=64 time=3.581 ms
15:13:51.453941 64 bytes from 192.168.45.15: icmp_seq=18599 ttl=64 time=3.341 ms
15:13:51.555197 64 bytes from 192.168.45.15: icmp_seq=18600 ttl=64 time=4.142 ms
15:13:51.658925 64 bytes from 192.168.45.15: icmp_seq=18601 ttl=64 time=2.709 ms
15:13:51.759479 64 bytes from 192.168.45.15: icmp_seq=18602 ttl=64 time=2.752 ms
15:13:51.861661 64 bytes from 192.168.45.15: icmp_seq=18603 ttl=64 time=4.685 ms
15:13:51.965549 64 bytes from 192.168.45.15: icmp_seq=18604 ttl=64 time=3.441 ms
15:13:52.069894 64 bytes from 192.168.45.15: icmp_seq=18605 ttl=64 time=2.620 ms
15:13:52.175146 64 bytes from 192.168.45.15: icmp_seq=18606 ttl=64 time=2.925 ms
15:13:52.276973 64 bytes from 192.168.45.15: icmp_seq=18607 ttl=64 time=3.539 ms
15:13:52.376560 64 bytes from 192.168.45.15: icmp_seq=18608 ttl=64 time=2.825 ms
15:13:52.481966 64 bytes from 192.168.45.15: icmp_seq=18609 ttl=64 time=3.103 ms
15:13:52.586966 64 bytes from 192.168.45.15: icmp_seq=18610 ttl=64 time=3.017 ms
15:13:52.692450 64 bytes from 192.168.45.15: icmp_seq=18611 ttl=64 time=3.359 ms
15:13:52.793824 64 bytes from 192.168.45.15: icmp_seq=18612 ttl=64 time=3.725 ms
15:13:52.898012 64 bytes from 192.168.45.15: icmp_seq=18613 ttl=64 time=3.438 ms
15:13:53.002531 64 bytes from 192.168.45.15: icmp_seq=18614 ttl=64 time=2.820 ms
15:13:53.104508 64 bytes from 192.168.45.15: icmp_seq=18615 ttl=64 time=4.345 ms
15:13:53.203563 64 bytes from 192.168.45.15: icmp_seq=18616 ttl=64 time=2.941 ms
15:13:53.309389 64 bytes from 192.168.45.15: icmp_seq=18617 ttl=64 time=3.625 ms
15:13:53.412038 64 bytes from 192.168.45.15: icmp_seq=18618 ttl=64 time=3.038 ms
15:13:53.517397 64 bytes from 192.168.45.15: icmp_seq=18619 ttl=64 time=4.968 ms
15:13:53.620569 64 bytes from 192.168.45.15: icmp_seq=18620 ttl=64 time=3.237 ms
15:13:53.721986 64 bytes from 192.168.45.15: icmp_seq=18621 ttl=64 time=4.030 ms
15:13:53.825622 64 bytes from 192.168.45.15: icmp_seq=18622 ttl=64 time=2.561 ms
15:13:53.940124 64 bytes from 192.168.45.15: icmp_seq=18623 ttl=64 time=16.758 ms
15:13:54.025890 64 bytes from 192.168.45.15: icmp_seq=18624 ttl=64 time=2.112 ms
15:13:54.129148 64 bytes from 192.168.45.15: icmp_seq=18625 ttl=64 time=2.888 ms
15:13:54.229235 64 bytes from 192.168.45.15: icmp_seq=18626 ttl=64 time=2.740 ms
15:13:54.334486 64 bytes from 192.168.45.15: icmp_seq=18627 ttl=64 time=4.463 ms
15:13:54.437575 64 bytes from 192.168.45.15: icmp_seq=18628 ttl=64 time=4.584 ms
15:13:54.537454 64 bytes from 192.168.45.15: icmp_seq=18629 ttl=64 time=3.448 ms
15:13:54.640582 64 bytes from 192.168.45.15: icmp_seq=18630 ttl=64 time=3.283 ms
15:13:54.744131 64 bytes from 192.168.45.15: icmp_seq=18631 ttl=64 time=4.029 ms
15:13:54.845859 64 bytes from 192.168.45.15: icmp_seq=18632 ttl=64 time=3.179 ms
15:13:54.947478 64 bytes from 192.168.45.15: icmp_seq=18633 ttl=64 time=2.827 ms
15:13:55.052476 64 bytes from 192.168.45.15: icmp_seq=18634 ttl=64 time=5.650 ms
15:13:55.154552 64 bytes from 192.168.45.15: icmp_seq=18635 ttl=64 time=3.871 ms
15:13:55.258871 64 bytes from 192.168.45.15: icmp_seq=18636 ttl=64 time=3.038 ms
15:13:55.359884 64 bytes from 192.168.45.15: icmp_seq=18637 ttl=64 time=3.102 ms
15:13:55.461159 64 bytes from 192.168.45.15: icmp_seq=18638 ttl=64 time=4.039 ms
15:13:55.562248 64 bytes from 192.168.45.15: icmp_seq=18639 ttl=64 time=3.183 ms
15:13:55.667160 64 bytes from 192.168.45.15: icmp_seq=18640 ttl=64 time=4.194 ms
15:13:55.887877 64 bytes from 192.168.45.15: icmp_seq=18641 ttl=64 time=124.260 ms
15:13:55.887931 64 bytes from 192.168.45.15: icmp_seq=18642 ttl=64 time=19.149 ms
15:13:56.011081 64 bytes from 192.168.45.15: icmp_seq=18643 ttl=64 time=40.408 ms
15:13:56.210344 64 bytes from 192.168.45.15: icmp_seq=18644 ttl=64 time=139.222 ms
15:13:56.210391 64 bytes from 192.168.45.15: icmp_seq=18645 ttl=64 time=34.771 ms
15:13:56.350011 64 bytes from 192.168.45.15: icmp_seq=18646 ttl=64 time=71.301 ms
15:13:56.538577 64 bytes from 192.168.45.15: icmp_seq=18647 ttl=64 time=156.479 ms
15:13:56.538627 64 bytes from 192.168.45.15: icmp_seq=18648 ttl=64 time=56.158 ms
15:13:56.627752 64 bytes from 192.168.45.15: icmp_seq=18649 ttl=64 time=42.300 ms
15:13:56.734975 64 bytes from 192.168.45.15: icmp_seq=18650 ttl=64 time=44.869 ms
15:13:56.916944 64 bytes from 192.168.45.15: icmp_seq=18651 ttl=64 time=123.662 ms
15:13:56.917004 64 bytes from 192.168.45.15: icmp_seq=18652 ttl=64 time=22.945 ms
15:13:57.097255 64 bytes from 192.168.45.15: icmp_seq=18653 ttl=64 time=100.624 ms
15:13:57.098835 64 bytes from 192.168.45.15: icmp_seq=18654 ttl=64 time=1.497 ms
15:13:57.278506 64 bytes from 192.168.45.15: icmp_seq=18655 ttl=64 time=79.731 ms
15:13:57.303504 64 bytes from 192.168.45.15: icmp_seq=18656 ttl=64 time=2.969 ms
15:13:57.460359 64 bytes from 192.168.45.15: icmp_seq=18657 ttl=64 time=56.355 ms
15:13:57.614368 64 bytes from 192.168.45.15: icmp_seq=18658 ttl=64 time=106.021 ms
15:13:57.614422 64 bytes from 192.168.45.15: icmp_seq=18659 ttl=64 time=3.553 ms
15:13:57.795755 64 bytes from 192.168.45.15: icmp_seq=18660 ttl=64 time=80.417 ms
15:13:57.822536 64 bytes from 192.168.45.15: icmp_seq=18661 ttl=64 time=2.305 ms
15:13:57.974278 64 bytes from 192.168.45.15: icmp_seq=18662 ttl=64 time=51.962 ms
15:13:58.152339 64 bytes from 192.168.45.15: icmp_seq=18663 ttl=64 time=128.924 ms
15:13:58.152359 64 bytes from 192.168.45.15: icmp_seq=18664 ttl=64 time=23.837 ms
15:13:58.333419 64 bytes from 192.168.45.15: icmp_seq=18665 ttl=64 time=99.724 ms
15:13:58.335526 64 bytes from 192.168.45.15: icmp_seq=18666 ttl=64 time=1.669 ms
15:13:58.513027 64 bytes from 192.168.45.15: icmp_seq=18667 ttl=64 time=78.029 ms
15:13:58.667726 64 bytes from 192.168.45.15: icmp_seq=18668 ttl=64 time=130.366 ms
15:13:58.667775 64 bytes from 192.168.45.15: icmp_seq=18669 ttl=64 time=26.966 ms
15:13:58.849483 64 bytes from 192.168.45.15: icmp_seq=18670 ttl=64 time=104.263 ms
15:13:58.849538 64 bytes from 192.168.45.15: icmp_seq=18671 ttl=64 time=4.126 ms
15:13:59.025957 64 bytes from 192.168.45.15: icmp_seq=18672 ttl=64 time=80.084 ms
15:13:59.053476 64 bytes from 192.168.45.15: icmp_seq=18673 ttl=64 time=2.443 ms
15:13:59.205727 64 bytes from 192.168.45.15: icmp_seq=18674 ttl=64 time=50.688 ms
15:13:59.388851 64 bytes from 192.168.45.15: icmp_seq=18675 ttl=64 time=132.034 ms
15:13:59.388898 64 bytes from 192.168.45.15: icmp_seq=18676 ttl=64 time=31.738 ms
15:13:59.566273 64 bytes from 192.168.45.15: icmp_seq=18677 ttl=64 time=105.030 ms
15:13:59.567464 64 bytes from 192.168.45.15: icmp_seq=18678 ttl=64 time=2.476 ms
15:13:59.722718 64 bytes from 192.168.45.15: icmp_seq=18679 ttl=64 time=55.094 ms
15:13:59.904533 64 bytes from 192.168.45.15: icmp_seq=18680 ttl=64 time=136.794 ms
15:13:59.904562 64 bytes from 192.168.45.15: icmp_seq=18681 ttl=64 time=31.656 ms
15:13:59.975121 64 bytes from 192.168.45.15: icmp_seq=18682 ttl=64 time=1.640 ms
15:14:00.077185 64 bytes from 192.168.45.15: icmp_seq=18683 ttl=64 time=3.313 ms
15:14:00.182709 64 bytes from 192.168.45.15: icmp_seq=18684 ttl=64 time=3.706 ms
15:14:00.284626 64 bytes from 192.168.45.15: icmp_seq=18685 ttl=64 time=4.542 ms
15:14:00.388569 64 bytes from 192.168.45.15: icmp_seq=18686 ttl=64 time=3.346 ms
15:14:00.493400 64 bytes from 192.168.45.15: icmp_seq=18687 ttl=64 time=3.185 ms
15:14:00.596481 64 bytes from 192.168.45.15: icmp_seq=18688 ttl=64 time=3.349 ms
15:14:00.702054 64 bytes from 192.168.45.15: icmp_seq=18689 ttl=64 time=4.081 ms
15:14:00.805155 64 bytes from 192.168.45.15: icmp_seq=18690 ttl=64 time=4.006 ms
15:14:00.909215 64 bytes from 192.168.45.15: icmp_seq=18691 ttl=64 time=3.350 ms
15:14:01.009992 64 bytes from 192.168.45.15: icmp_seq=18692 ttl=64 time=3.029 ms
15:14:01.115744 64 bytes from 192.168.45.15: icmp_seq=18693 ttl=64 time=3.763 ms
15:14:01.220619 64 bytes from 192.168.45.15: icmp_seq=18694 ttl=64 time=3.500 ms
15:14:01.321086 64 bytes from 192.168.45.15: icmp_seq=18695 ttl=64 time=3.196 ms
15:14:01.424817 64 bytes from 192.168.45.15: icmp_seq=18696 ttl=64 time=3.374 ms
15:14:01.526764 64 bytes from 192.168.45.15: icmp_seq=18697 ttl=64 time=3.218 ms
15:14:01.626670 64 bytes from 192.168.45.15: icmp_seq=18698 ttl=64 time=2.983 ms
15:14:01.727089 64 bytes from 192.168.45.15: icmp_seq=18699 ttl=64 time=3.251 ms
15:14:01.832038 64 bytes from 192.168.45.15: icmp_seq=18700 ttl=64 time=3.070 ms
15:14:01.938856 64 bytes from 192.168.45.15: icmp_seq=18701 ttl=64 time=4.761 ms
15:14:02.042751 64 bytes from 192.168.45.15: icmp_seq=18702 ttl=64 time=3.465 ms
15:14:02.146580 64 bytes from 192.168.45.15: icmp_seq=18703 ttl=64 time=3.512 ms
15:14:02.251306 64 bytes from 192.168.45.15: icmp_seq=18704 ttl=64 time=3.104 ms
15:14:02.353058 64 bytes from 192.168.45.15: icmp_seq=18705 ttl=64 time=4.010 ms
15:14:02.459943 64 bytes from 192.168.45.15: icmp_seq=18706 ttl=64 time=5.713 ms
15:14:02.561523 64 bytes from 192.168.45.15: icmp_seq=18707 ttl=64 time=4.595 ms
15:14:02.665287 64 bytes from 192.168.45.15: icmp_seq=18708 ttl=64 time=3.227 ms
15:14:02.769998 64 bytes from 192.168.45.15: icmp_seq=18709 ttl=64 time=2.829 ms
15:14:02.872255 64 bytes from 192.168.45.15: icmp_seq=18710 ttl=64 time=2.867 ms
15:14:02.975476 64 bytes from 192.168.45.15: icmp_seq=18711 ttl=64 time=2.713 ms
15:14:03.076583 64 bytes from 192.168.45.15: icmp_seq=18712 ttl=64 time=2.969 ms
15:14:03.177461 64 bytes from 192.168.45.15: icmp_seq=18713 ttl=64 time=3.573 ms
15:14:03.281007 64 bytes from 192.168.45.15: icmp_seq=18714 ttl=64 time=5.842 ms
15:14:03.383050 64 bytes from 192.168.45.15: icmp_seq=18715 ttl=64 time=2.695 ms
15:14:03.482827 64 bytes from 192.168.45.15: icmp_seq=18716 ttl=64 time=2.294 ms
15:14:03.583841 64 bytes from 192.168.45.15: icmp_seq=18717 ttl=64 time=2.768 ms
15:14:03.689275 64 bytes from 192.168.45.15: icmp_seq=18718 ttl=64 time=3.464 ms
15:14:03.793349 64 bytes from 192.168.45.15: icmp_seq=18719 ttl=64 time=3.068 ms
15:14:03.895009 64 bytes from 192.168.45.15: icmp_seq=18720 ttl=64 time=2.290 ms
15:14:03.999122 64 bytes from 192.168.45.15: icmp_seq=18721 ttl=64 time=3.526 ms
15:14:04.104748 64 bytes from 192.168.45.15: icmp_seq=18722 ttl=64 time=4.073 ms
15:14:04.209313 64 bytes from 192.168.45.15: icmp_seq=18723 ttl=64 time=3.929 ms
15:14:04.310137 64 bytes from 192.168.45.15: icmp_seq=18724 ttl=64 time=3.181 ms
15:14:04.415366 64 bytes from 192.168.45.15: icmp_seq=18725 ttl=64 time=3.483 ms
15:14:04.520522 64 bytes from 192.168.45.15: icmp_seq=18726 ttl=64 time=3.454 ms
15:14:04.625508 64 bytes from 192.168.45.15: icmp_seq=18727 ttl=64 time=3.996 ms
15:14:04.725340 64 bytes from 192.168.45.15: icmp_seq=18728 ttl=64 time=3.584 ms
15:14:04.825540 64 bytes from 192.168.45.15: icmp_seq=18729 ttl=64 time=3.665 ms
15:14:04.925844 64 bytes from 192.168.45.15: icmp_seq=18730 ttl=64 time=2.996 ms
15:14:05.027766 64 bytes from 192.168.45.15: icmp_seq=18731 ttl=64 time=4.130 ms
15:14:05.131772 64 bytes from 192.168.45.15: icmp_seq=18732 ttl=64 time=2.996 ms
15:14:05.231973 64 bytes from 192.168.45.15: icmp_seq=18733 ttl=64 time=2.751 ms
15:14:05.333320 64 bytes from 192.168.45.15: icmp_seq=18734 ttl=64 time=2.598 ms
15:14:05.434894 64 bytes from 192.168.45.15: icmp_seq=18735 ttl=64 time=3.352 ms
15:14:05.536309 64 bytes from 192.168.45.15: icmp_seq=18736 ttl=64 time=3.113 ms
15:14:05.640387 64 bytes from 192.168.45.15: icmp_seq=18737 ttl=64 time=3.027 ms
15:14:05.743883 64 bytes from 192.168.45.15: icmp_seq=18738 ttl=64 time=3.572 ms
15:14:05.843831 64 bytes from 192.168.45.15: icmp_seq=18739 ttl=64 time=3.351 ms
15:14:05.943805 64 bytes from 192.168.45.15: icmp_seq=18740 ttl=64 time=2.808 ms
15:14:06.044698 64 bytes from 192.168.45.15: icmp_seq=18741 ttl=64 time=2.488 ms
15:14:06.146057 64 bytes from 192.168.45.15: icmp_seq=18742 ttl=64 time=2.596 ms
15:14:06.252273 64 bytes from 192.168.45.15: icmp_seq=18743 ttl=64 time=4.516 ms
15:14:06.355264 64 bytes from 192.168.45.15: icmp_seq=18744 ttl=64 time=2.684 ms
...

Note the culprit by the corresponding timestamps from /var/log/wifi.log on your Apple device (MacBook in this case):

Summary
...
Sat Sep  5 15:13:55.666 Info: <airport[16127]> SCAN request received from pid 106 (locationd) with priority=2, qos=-1 (default), frontmost=no
Sat Sep  5 15:13:56.009 Driver Event: <airport[16127]> _bsd_80211_event_callback: SCAN_CACHE_UPDATED (en0)
Sat Sep  5 15:13:56.010 AutoJoin: <airport[16127]> Successful cache-assisted scan request for locationd with channels {(
Sat Sep  5 15:13:56.010     <CWChannel: 0x7fcb31e515f0> [channelNumber=1(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.010     <CWChannel: 0x7fcb31e1f6c0> [channelNumber=2(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.010     <CWChannel: 0x7fcb31e21ec0> [channelNumber=3(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.010     <CWChannel: 0x7fcb31e500a0> [channelNumber=4(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.010     <CWChannel: 0x7fcb31e47d30> [channelNumber=5(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.010     <CWChannel: 0x7fcb31e513f0> [channelNumber=6(2GHz), channelWidth={20MHz}, active]
Sat Sep  5 15:13:56.010 )} took 0.3435 seconds, returned 3 results
Sat Sep  5 15:13:56.023 Info: <airport[16127]> TRIMMED QUERY SCAN CACHE request received from pid 106 (locationd)
Sat Sep  5 15:13:56.347 Driver Event: <airport[16127]> _bsd_80211_event_callback: SCAN_CACHE_UPDATED (en0)
Sat Sep  5 15:13:56.348 AutoJoin: <airport[16127]> Successful cache-assisted scan request for locationd with channels {(
Sat Sep  5 15:13:56.348     <CWChannel: 0x7fcb31e51f80> [channelNumber=7(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.348     <CWChannel: 0x7fcb31e52060> [channelNumber=8(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.348     <CWChannel: 0x7fcb31e46e80> [channelNumber=9(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.348     <CWChannel: 0x7fcb31e1a230> [channelNumber=10(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.348     <CWChannel: 0x7fcb31e1e560> [channelNumber=11(2GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:56.348     <CWChannel: 0x7fcb31e239c0> [channelNumber=36(5GHz), channelWidth={40MHz(+1)}, active]
Sat Sep  5 15:13:56.348 )} took 0.3375 seconds, returned 7 results
Sat Sep  5 15:13:56.361 Info: <airport[16127]> TRIMMED QUERY SCAN CACHE request received from pid 106 (locationd)
Sat Sep  5 15:13:56.627 Driver Event: <airport[16127]> _bsd_80211_event_callback: SCAN_CACHE_UPDATED (en0)
Sat Sep  5 15:13:56.628 AutoJoin: <airport[16127]> Successful cache-assisted scan request for locationd with channels {(
Sat Sep  5 15:13:56.628     <CWChannel: 0x7fcb31e518f0> [channelNumber=40(5GHz), channelWidth={40MHz(-1)}, active],
Sat Sep  5 15:13:56.628     <CWChannel: 0x7fcb31e1a860> [channelNumber=44(5GHz), channelWidth={40MHz(+1)}, active],
Sat Sep  5 15:13:56.628     <CWChannel: 0x7fcb31e19d70> [channelNumber=48(5GHz), channelWidth={40MHz(-1)}, active],
Sat Sep  5 15:13:56.628     <CWChannel: 0x7fcb31e1fd10> [channelNumber=149(5GHz), channelWidth={80MHz}, active],
Sat Sep  5 15:13:56.628     <CWChannel: 0x7fcb31e24940> [channelNumber=153(5GHz), channelWidth={80MHz}, active],
Sat Sep  5 15:13:56.628     <CWChannel: 0x7fcb31e2d6e0> [channelNumber=157(5GHz), channelWidth={80MHz}, active]
Sat Sep  5 15:13:56.628 )} took 0.2795 seconds, returned 5 results
Sat Sep  5 15:13:56.641 Info: <airport[16127]> TRIMMED QUERY SCAN CACHE request received from pid 106 (locationd)
Sat Sep  5 15:13:57.458 AutoJoin: <airport[16127]> Successful cache-assisted scan request for locationd with channels {(
Sat Sep  5 15:13:57.459     <CWChannel: 0x7fcb31e423c0> [channelNumber=161(5GHz), channelWidth={80MHz}, active],
Sat Sep  5 15:13:57.459     <CWChannel: 0x7fcb31e51370> [channelNumber=165(5GHz), channelWidth={20MHz}, active],
Sat Sep  5 15:13:57.459     <CWChannel: 0x7fcb31e18600> [channelNumber=12(2GHz), channelWidth={20MHz}],
Sat Sep  5 15:13:57.459     <CWChannel: 0x7fcb31e18a00> [channelNumber=13(2GHz), channelWidth={20MHz}],
Sat Sep  5 15:13:57.459     <CWChannel: 0x7fcb31e358c0> [channelNumber=52(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:57.459     <CWChannel: 0x7fcb31e32710> [channelNumber=56(5GHz), channelWidth={40MHz(-1)}]
Sat Sep  5 15:13:57.459 )} took 0.8299 seconds, returned 0 results
Sat Sep  5 15:13:58.512 AutoJoin: <airport[16127]> Successful cache-assisted scan request for locationd with channels {(
Sat Sep  5 15:13:58.512     <CWChannel: 0x7fcb31e452c0> [channelNumber=60(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:58.512     <CWChannel: 0x7fcb31e22e10> [channelNumber=64(5GHz), channelWidth={40MHz(-1)}],
Sat Sep  5 15:13:58.512     <CWChannel: 0x7fcb31e361c0> [channelNumber=100(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:58.512     <CWChannel: 0x7fcb31e50420> [channelNumber=104(5GHz), channelWidth={40MHz(-1)}],
Sat Sep  5 15:13:58.512     <CWChannel: 0x7fcb31e4dce0> [channelNumber=108(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:58.512     <CWChannel: 0x7fcb31e523e0> [channelNumber=112(5GHz), channelWidth={40MHz(-1)}]
Sat Sep  5 15:13:58.512 )} took 1.0530 seconds, returned 0 results
Sat Sep  5 15:13:59.565 AutoJoin: <airport[16127]> Successful cache-assisted scan request for locationd with channels {(
Sat Sep  5 15:13:59.566     <CWChannel: 0x7fcb31e525f0> [channelNumber=116(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:59.566     <CWChannel: 0x7fcb31e51de0> [channelNumber=120(5GHz), channelWidth={40MHz(-1)}],
Sat Sep  5 15:13:59.566     <CWChannel: 0x7fcb31e54c50> [channelNumber=124(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:59.566     <CWChannel: 0x7fcb31e1e7e0> [channelNumber=128(5GHz), channelWidth={40MHz(-1)}],
Sat Sep  5 15:13:59.566     <CWChannel: 0x7fcb31e34540> [channelNumber=132(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:59.566     <CWChannel: 0x7fcb31e48360> [channelNumber=136(5GHz), channelWidth={40MHz(-1)}]
Sat Sep  5 15:13:59.566 )} took 1.0534 seconds, returned 0 results
Sat Sep  5 15:13:59.903 AutoJoin: <airport[16127]> Successful cache-assisted scan request for locationd with channels {(
Sat Sep  5 15:13:59.903     <CWChannel: 0x7fcb31e36380> [channelNumber=140(5GHz), channelWidth={40MHz(+1)}],
Sat Sep  5 15:13:59.903     <CWChannel: 0x7fcb31e454d0> [channelNumber=144(5GHz), channelWidth={40MHz(-1)}]
Sat Sep  5 15:13:59.903 )} took 0.3371 seconds, returned 0 results
Sat Sep  5 15:14:06.024 Info: <airport[16127]> TRIMMED QUERY SCAN CACHE request received from pid 496 (WiFiAgent)
Sat Sep  5 15:14:06.031 Info: <airport[16127]> QUERY GAS CACHE request received from pid 496 (WiFiAgent)
Sat Sep  5 15:14:06.031 Info: <airport[16127]> QUERY ALL WIFI NETWORKS request received from pid 496 (WiFiAgent)
Sat Sep  5 15:14:06.033 Info: <airport[16127]> GET CURRENT TETHER DEVICE request received from pid 496 (WiFiAgent)
Sat Sep  5 15:14:06.034 Info: <airport[16127]> QUERY ALL WIFI NETWORKS request received from pid 496 (WiFiAgent)
Sat Sep  5 15:14:06.035 Info: <airport[16127]> QUERY ALL WIFI NETWORKS request received from pid 496 (WiFiAgent)
...

See what happened there?
SCAN request received from pid 106 (locationd)

Yuck! In my case*, the locationd daemon initiated a channel scan. Depending on the services you have enabled in Location Services on your Apple device, the interval of this channel scan will vary. I have witnessed this channel scan run every 10 seconds in the past, but for me it is currently occurring every 5 by minutes. While I am thankful it's every five minutes vs 10 seconds, channel scans still suck (credit @dtaht).

You may be able to improve your situation if you experience the same by deselecting services you deem unnecessary from Location Services on your Apple device. I wish I could say I have found the right combo to eliminate this channel scan, but I think it is something I may have to live with for now given I choose to keep Find My Mac enabled.

*Note: It is not just locationd that initiates channel scans. You may find other apps initiate it as well. The app and PID in your particular log will help you identify the culprit.

I realize this is not specific to OpenWrt, but I care a lot about this community. I have chased my tail on this latency issue in the past and went down all sorts of ugly roads like switching WiFi drivers and firmware, as well as adding/rolling back patches in my OpenWrt builds trying to resolve this. I hope this helps save others some time by avoiding the same headaches if you end up chasing this same issue. :slight_smile:

** EDIT **
Some additional interesting information regarding latency due to awdl0. Somewhat dated, but likely still relevant:


3 Likes

WIP...

Location Services confirmed to trigger recurring WiFi channel scans:

System Services

  • Location-Based Suggestions @ 5min intervals (locationd)
  • Time Zone & System Customization @ 60min intervals (locationd)
  • Significant Locations @ 10min intervals (locationd)

Location Services which do not appear to trigger recurring WiFi channel scans (feedback is encouraged):

Location Services

  • Find My
  • Weather
  • Messages
  • Home
  • Reminders
  • Calendar
  • Wallet
  • Safari

System Services

  • Wi-Fi Calling

Happens on all MacBooks; disable location service and try again.

Agreed, but disabling all may not be necessary, nor desired. See my note about not wishing to disable Find My Mac.

My goal is to identify which specific services trigger channel scans. Feel free to join the effort if you would like.

It would be a service that triggers a wifi scan. You can reproduce the latency issue by clicking in the wifi icon at the top; Macbook starts scanning for available networks and you get the latency. I never tried to figure out what exactly causes it, because it seems to be a non-issue to me.