Windows/Apache Sysadmin – Fixing the unadvertised speed limit
This is a post for any Windows sysadmins out there who administrate a server using Apache and PHP.
For a while now, our Windows download servers at work have had some transfer speed issues. I would turn off all external traffic and try downloading a file directly, and it went nowhere near as quickly as it should have. Turns out, there were 2 problems.
Problem 1: PHP readfile() apparently sucks
The first thing I noticed was that directly downloading a file via Apache was much faster than using PHP to pass it through with readfile() for some reason. I fretted for a bit and ended up just doing this:
// Sends a file using fread, 16K at a time
function my_send_file($filename) {
$fp = fopen($filename, “rb”);
//start buffered download
if ($fp) {
while(!feof($fp)) {
print(fread($fp,1024*16));
flush(); ob_flush();
}
fclose($fp);
}
}
That made downloads go about 50% faster, but it still wasn’t near where it should be for some reason. I left well enough alone for a while until it piqued my curiosity again, and lo and behold I found a few hits on Google!
Problem 2: Windows ignores Apache SendBufferSize setting
This is a rather annoying bug. The only way to fix it is to edit the registry thusly:
- Open up regedit, then go to HKEY_LOCAL_MACHINE > SYSTEM > CurrentControlSet > Services > AFD > Parameters
- Create two DWORD values called “DefaultReceiveWindow” and “DefaultSendWindow”
- You then set both these values using DECIMAL (not Hex) using this formula:
DefaultReceiveWindow = (Download Capacity in Kbps * 1024) / 8
DefaultSendWindow = (Upload Capacity in Kbps * 1024) / 8
For example, for a 10Mbps (~10000 Kbps) upload and download:
DefaultReceiveWindow = (10000 * 1024) / 8 = 1280000
DefaultSendWindow = (10000 * 1024) / 8 = 1280000 - Reboot and test your Apache speed.
We saw a 4-6x increase in speed after doing this. It’s possible that problem 1 above was related to this, so maybe after doing this readfile() would work just as well as fread(). But it ain’t broke now, so I’m not going to fix it.