In earlier blogs in this series we talked about configuring and tuning Unix and Linux based servers for high performance systems. Now, I will talk about configuring Windows servers. Windows servers are traditionally not used as servers anymore, but there are some applications where Windows is still the only option. Unix, and primarily Linux, have become the go-to platforms for servers due to their security, relatively low setup and maintenance costs and high performance output. Windows servers aren’t as easy to maintain, have a large memory footprint and until more recently have been problematic when it comes to security. They do often make great simulator machines especially when you have some old commodity Windows boxes lying around.
Since Windows boxes aren’t nearly as customizable as Unix/Linux boxes, there aren’t quite as many parameters that need to be changed to optimize performance. There are some key settings that should be changed particularly if your application creates a large number of outbound network connections. Typically, a high performance web application or a simulator that is going to simulate a large number of clients will run into issues on Windows boxes prior to Windows 7 and Windows Vista. This is because the number of ephemeral ports for outbound connections that the server can create is severely restricted.
The official reason for this limitation appears to be to prevent too much kernel memory from being consumed by a large number of connections. Others have speculated this limit was also implemented to help control negative effects from compromised servers. Whatever the reasons, here are the settings you most likely will want to change.
MaxHashTableSize and MaxUserPort are the primary ones that I have had to change in the past, though the other settings below may help you out as well. MaxUserPort changes the range of ports (sometimes called ephemeral ports) from the limited 1024-5000 range to 1024-65534, while MaxHashTableSize determines the size of the hash table in which TCP control blocks (TCBs) are stored.
TcpTimedWaitDelay is similar to the net.ipv4.tcp_fin_timeout setting in Linux TCP Kernel settings. This determines how long the system waits before returning the port to the pool. If you have increased the MaxUserPort and still are running out of ephemeral ports, reducing this can help return ports to the pool faster. Be careful here since TCP is a stateless protocol and the timeout is there for a reason. Reducing this to 30 seconds seems to be okay and I have reduced it even further in my testing. MaxFreeTwTcbs controls the number of connections that can be in the TIME WAIT state. While NumTcbTablePartitions specifies the number of partitions in the Transport Control Block table.
You can save all of these to a .reg file and execute it on the server you want to make adjustments to. Make sure you are an administrator user to run this.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters] "TcpTimedWaitDelay"=dword:0000001e "MaxHashTableSize"=dword:00004000 "MaxFreeTwTcbs"=dword:00061a80 "MaxUserPort"=dword:0000fffe "NumTcbTablePartitions"=dword:00000020
Post Windows Vista and Windows 7 appear to handle networking differently. Commodity machines are typically older machines, though, and this will be an issue on those.