How can I speed up my Windows 7 tcp file transfers over a 100 mbps link between Chicago and London?
Right now, I am transferring two 4GB files in two sftp sessions. Each file transfer is running at a rate of 500 KB/s (4 Mbits/sec). (B == bytes, b == bits, naturally). This is quite slow, as iperf tests show a rate of 16.8 Mbits/sec for a single TCP stream. That's 2 MB/sec.
Starting the second sftp session does not affect the speed of the first one iota. This makes sense to me as I noticed that my iperf tests were limited under TCP- each connection was 16 Mbps which leaves room on the wire for more connections. I was able to make iperf saturate my line by running many parallel connections, and it was a linear increase in bandwidth. That is, with 5 parallel connections I achieved bandwidth of about 5x16 == 80 Mbps.
I note that local file transfers using sftp are around 30 MB/s... quite good. So I don't think SSH channel encryption is the bottleneck.
I have reviewed What is the best way to transfer a single large file over a high-speed, high-latency WAN link? as well as other serverfault questions and there are a lot of interesting tools but what I am looking for is a way for me to adjust Windows' TCP stack to make sure I get my full 2 MB at least... and maybe more, since the iPerf tests were across untuned machines.
I notice, too, that when I drag-and-drop a file on a London machine from my Chicago fileserver, it seems to transfer at quite a nice clip (as shown by looking at the details during the transfer) but after a few minutes it drops off the cliff into the 10's of Kbps. It was very odd.
My latency is steady at around 88 ms, so I think the network infrastructure is good. We have a dedicated line; this is not a VPN over the Internet or anything like that.
========
I have a Linux VM that is "close" to my Windows desktop, network-wise. That is, they are on different subnets but both machines go into switches that both go into another switch that goes to London. Right now I am running an sftp from Linux to London and it is running at 8 MB/s while my desktop continues at 500 KB/s.
======== Ok, I put my Linux laptop on exactly the same switch as my Desktop. Where the desktop is performing an sftp at 500 KB/s at this moment, the Linux laptop is sending a 4Gig file at 7.6 MB/s. To the same server in London, of course.
======== Another test: I was using SecureFX by VanDyke Corp. I also have Cygwin on my PC, and I just went and used the CLI sftp command there. I just increased my throughput fivefold... I'm now getting 2.5 MB/s instead of 500k! :-\ This is on par with my iPerf results of 16 Mbps. Which I would have been content with... although now I notice that my laptop is three times as fast as that.
======== Another test: On my London machine, I started a Windows Explorer file copy from my fileserver in Chicago to the locally-mounted Downloads folder (that is, on an internal hard drive). The throughput was a rock-steady 5.49 MB/s for 12 minutes or so. That's close enough to fine for me! And again, copying via SecureCRT was miserably slow- a steady 500 KB/s.
The only thing I can conclude is that although there may be TCP tweaks that will help, the app you use can make a big difference! Furthermore, I don't know why my filecopy acted so strangely the other day. If it happens again I will attempt to debug.
Thanks for the suggestions and replies.
======================
Ok, I have followed Todd Wilcox' links and figured a few things out:
- First, according to Microsoft, from https://technet.microsoft.com/en-us/library/cc957546.aspx?f=255&MSPPError=-2147217396, "TCP uses a receive window... For Ethernet networks, the default value of this entry is 0x4470 (17,520, or 12 segments of 1,460 bytes each)" Well I have a WAN with 80ms latency so this is much too small.
- I have set both GlobalMaxTcpWindowSize and TcpWindowSize in the registry (the latter on my adapter) to 1 MiB, then went to the command line and used
netsh
to change the Receive Window Auto-Tuning Level from normal to disabled. My network transfer speeds did not change, so I rebooted my machine and again performed an sftp from my desktop to the London server. - Throughput plummeted to 700 KB/s. Needless to say, I set everything back and rebooted again. Now my throughput is back to 2.1 MB/s.
- During the sftp, Wireshark shows a strange sawtooth pattern to the TCP window scaling, going from about 64000 to 62000 bytes then back up again. The cycle takes about 35 seconds.
- Let's say that my average is 63000 bytes window size. Therefore, my Bps throughput should be (from http://bradhedlund.com/2008/12/19/how-to-calculate-tcp-throughput-for-long-distance-links/), Window-Size (bytes) / Latency (sec) == 700 KB/s. Strange that I'm getting 2.1 MB/s... that's higher than the theoretical! I'm sure there are no Wan accelerators in between or anything more complicated than a Cisco 4948. Maybe Wireshark's window scaling graph is not the same as the window size, I don't know, but Googling told me that that was where I'd find the TCP window size.
- Things aren't adding up. Although I did find that my twiddling did screw things up, I don't know how to definitively tell what my TCP window sizes are. Furthermore, the oft-sited Brad Hedlund page gives some calculations that are not reflected in my experience.
- Finally, and this is the greatest lesson I have learned: I think I'll leave well enough alone. If we find we need better throughput, maybe I'll recommend a WAN accelerator. But since we're going halfway across the world we oughtn't expect phenomenal bandwidth from a single TCP connection.
Formula to calculate optimal TCP window size (source):
In your case: 100 000 000 * .088 = 8 800 000 bits or 1 100 000 bytes
This is configurable in the Windows registry in the TcpWindowSize key in a valid range of 0–0x3FFFFFFF (1 073 741 823 decimal), so that figure is in the valid range.
The default value is the smallest of the following (Note: "Values greater than 64 KB can be achieved only when connecting to other systems that support RFC 1323 Window Scaling"):
Source (This link is now mostly dead - slightly alive, but only a miracle could bring it back)
Also see: http://bradhedlund.com/2008/12/19/how-to-calculate-tcp-throughput-for-long-distance-links/
And: https://technet.microsoft.com/en-us/library/cc938219.aspx