2008-03-04

A Fix for Slow WiFi 802.11 File Transfers under Mac OS X Leopard 10.5.2

While trying to transfer files from a wired iMac running 10.5.2 to a wireless MacBook Pro running 10.5.2, I ran into extremely slow transfers.

I was attempting to copy the free part of Nine Inch Nails' new album and decided to leave the slow transfer plodding along, while I researched the issue. It seems I was not the only one having this problem (Apple Support Discussion link).

It appears likely the problem has crept in with the 10.5.2 update, and it dramatically slows wireless transfers under some conditions. It seems to affect a variety of wireless Macs connecting through a variety of wireless router brands including Apple.

Based on some of the posts, it appears the problem is related to "silly window syndrome" which causes confusion with the normal packet acknowledgment process in TCP/IP. Due to this confusion (which may be caused by edge cases of transfer size and timing), both machines basically pause waiting for the other to say go. In the fast and furious world of TCP/IP, this shows itself as a dramtic slow down in large transfers, while it may not be so noticeable in smaller transfers.

But there is a fix (or at least a workaround). You can change your Mac's default ACK setting from 3 to 0 with the following Terminal command:

sudo sysctl -w net.inet.tcp.delayed_ack=0

And you change it back to the default of 3 with:

sudo sysctl -w net.inet.tcp.delayed_ack=3

Or you can simply check you existing setting with:

sudo sysctl net.inet.tcp.delayed_ack

Note: You will likely need to preface any command changing these settings with "sudo" and enter your admin password to use your root account privileges.

Hopefully, Apple will roll out a more elegant and more permanent solution soon.



Additional Links:
Related Technical Paper
Script to make the ACK change on login
MacOSXHints

12 comments:

Pleaseluggage said...

sysctl: net.inet.tcp.delayed_ack: Operation not permitted

I've fixed my permissions and I'm admin in 10.5.2. What did I do wrong?

John@OC said...

You probably need to preface the command with "sudo" and enter your admin password.

sudo sysctl -w net.inet.tcp.delayed_ack=0

You need root rights to affect the change.

Fuzzbear said...

i get a Command not found when trying to verify the current level.

John@OC said...

sysctl is a standard part of OSX. If your shell path is messed up, that might give the error. You may want to copy and paste to verify, just in case:

sysctl net.inet.tcp.delayed_ack

You may need to "sudo" the command to make a change.

Yermun said...

Gee, thanks. This fix solved my problem of low internet speed - and I´ve tried a lot of them - including DNS, spotlight prefs. aso. I was nearly giving up on TC. Now I´m only excited if it works for Time Machine as well. I´ll report back on that.

John B. Osborne said...

Just curious: what Mac OS X version is everyone using who has the problem? What about folks who are not experiencing this problem?

I had hoped Apple would have fixed this issue in 10.5.3, but I haven't had a chance to test it yet.

Thanks.

Yermun said...

I have got version 10.5.3 - sad, but true.

Yermun said...

To make TM do a WIRELESS backup as well I had to do two more fixes:

1) This one http://www.trajiklyhip.com/blog/index.cfm/2008/5/18/A-Fix-for-Time-Machines-Backup-Failure
(which really didnt change anything untill I did nr 2...

2) In the Airport-tool I changed TC´s channel from 7 (my own setting) to «automatic», which is default

and HURRAY. It works.

Misha said...

I whant to set it permanently.
After typing in terminal
echo net.inet.tcp.delayed_ack=0 >> /etc/sysctl.conf
or
sudo echo net.inet.tcp.delayed_ack=0 >> /etc/sysctl.conf
I’m getting ‘Permission denied’ error, what do I do wrong?

John B. Osborne said...

@Misha

I'm not sure about using "echo" to manually edit the that file. The "sysctl" command will change the setting (or allow you to check its current setting).

I recommend "sudo sysctl -w net.inet.tcp.delayed_ack=0" to change it, "sudo sysctl -w net.inet.tcp.delayed_ack=3" to change it back to the default, and "sudo sysctl net.inet.tcp.delayed_ack" to check its current setting.

Tell me if that works for you.

someara said...

use:

sudo bash -c "echo "net.inet.tcp.delayed_ack=0" >> /etc/sysctl.conf"

also...

net.inet.tcp.recvspace=40960
(better buffer setting)

net.inet.tcp.rfc1323=0
(the underlying reason using the delayed_ack thing works)

someara said...

er... sorry... it's late...

what i meant to say was:

sudo bash -c "echo 'net.inet.tcp.delayed_ack=0' >> /etc/sysctl.conf"

sudo bash -c "echo 'net.inet.tcp.recvspace=40960' >> /etc/sysctl.conf"

sudo bash -c "echo 'net.inet.tcp.rfc1323=0' >> /etc/sysctl.conf"


Those commands will take effect after a reboot.

sysctl -w parameter=value will take effect immediately, but not survive a reboot.