When you have set up your ASP.NET / .NET or PHP configuration for high performing websites in Windows Server, it sometimes becomes important to reconfigure Windows Server’s TCP/IP stack and IIS too. You may have to increase network throughput and performance, or you just might run out of available ports / sockets (aka port exhaustion). And, as you know, fast page loads are more and more important nowadays for seach engine optimization (SEO) and user experience. Therefore we’ll dive into tuning IIS and TCP/IP stack for high performance websites and high volume of web requests a bit.
Please note that this is a repost of an older (old) post of mine that I had removed. Want the original? Look it up at the Wayback machine. I repost this because parts are still important for high performing websites and webservers.
In this small post I’ll guide you through the various IIS and Windows Server configuration settings, for high performance websites and high volume of web requests.
IIS limits for a website
The <limits> element of the element configures settings that limit the amount of bandwidth, the number of connections, or the connection time-out for client requests to a site.
If the <limits>
element is configured in both the <siteDefaults>
section and in the <site>
section for a specific site, the configuration in the <site>
section is used for that site.
IIS Connection Timeout
IIS’ default Connection Timeout for HTTP requests is 120 seconds. This means that a connection will remain open for two minutes, even when the client has disconnected (e.g, clicked a link and left to a different website). You can safely reduce this to 60 or 30 seconds, depending on your needs, with AppCmd:
appcmd.exe set config
-section:system.applicationHost/sites
"/[name='example.com'].limits.connectionTimeout:00:01:00"
/commit:apphost
Code language: JavaScript (javascript)
Or globally for all sites:
appcmd.exe set config
-section:system.applicationHost/sites
/siteDefaults.limits.connectionTimeout:"00:01:00"
/commit:apphost
Code language: PowerShell (powershell)
appcmd.exe set config
-section:system.applicationHost/webLimits
/connectionTimeout:"00:01:00"
/commit:apphost
Code language: PowerShell (powershell)
Notice <limits> and <webLimits>. This releases sockets that are waiting in a TIME_WAIT state, faster because the <webLimits>
element specifies TCP/IP connection and bandwidth limits, whereas the <limits>
element configures default settings that limit the amount of bandwidth, the number of connections, or the connection time-out for client requests for a Web server.
You can get the number of current connections using PowerShell, listed per website if necessary.
IIS maxConnections
Use the following AppCmd command to increase -or decrease- the number of maximum number of connections for a site. Use this setting to limit the number of simultaneous client connections.
appcmd.exe set config
-section:system.applicationHost/sites
"/[name='example.com'].limits.maxConnections:1500"
/commit:apphost
Code language: PowerShell (powershell)
Ephemeral ports
This one is important with Windows Server 2012 R2 and below, and became less imortant with newer Windows Server versions.
An ephemeral port is a communications endpoint, or port. The number of available ephemeral ports is limited and differs per Windows Server version. Please be aware of that and don’t just type over commands supposed to increase the amount of available ports to resolve port exhaustion. You may end up lowering the ports availabe… Basicly you have 65535 ports and the first 1024 are reserved. Of the remaining 64511, Windows has a subset configured for use.
If we take a tour down memory lane, you may find KB929851, where you read:
To comply with Internet Assigned Numbers Authority (IANA) recommendations, Microsoft has increased the dynamic client port range for outgoing connections in Windows Vista and Windows Server 2008. The new default start port is 49152, and the new default end port is 65535. This is a change from the configuration of earlier versions of Windows that used a default port range of 1025 through 5000.
To look up the default for your Windows Server version, use the netsh.exe
command:
netsh int ipv4 show dynamicport tcp
netsh int ipv4 show dynamicport udp
netsh int ipv6 show dynamicport tcp
netsh int ipv6 show dynamicport udp
Code language: PowerShell (powershell)
My Windows 11 workstation returns:
PS C:\Users\Jan Reilink> netsh int ipv4 show dynamicport tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
PS C:\Users\Jan Reilink> netsh int ipv4 show dynamicport udp
Protocol udp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
PS C:\Users\Jan Reilink> netsh int ipv6 show dynamicport tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
PS C:\Users\Jan Reilink> netsh int ipv6 show dynamicport udp
Protocol udp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
Code language: PowerShell (powershell)
And as you can see my old Windows Server 2012 R2 VM has the same ports configured:
PS C:\Windows\system32> Get-ComputerInfo | Select-Object OSName,OSVersion
OsName OsVersion
------ ---------
Microsoft Windows Server 2012 R2 Standard 6.3.9600
PS C:\Windows\system32> netsh int ipv4 show dynamicport tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
PS C:\Windows\system32> netsh int ipv4 show dynamicport udp
Protocol udp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
PS C:\Windows\system32> netsh int ipv6 show dynamicport tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
PS C:\Windows\system32> netsh int ipv6 show dynamicport udp
Protocol udp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
Code language: PowerShell (powershell)
Long story short: do your investigations first before you make reckless changes. If, and only if, you need to increase this MaxUserPort configuraton, read on.
The TCP MaxUserPort configuration is something different than IIS’ MaxUrlLength, keep this in mind.
MaxUserPort
The number of available short-lived (or ephemeral) ports differs per Windows Server version. In the early Windows 2003 days, ephemeral ports are allocated between the values of 1024 and 5000 inclusive. The MaxUserPort value controls the maximum port number used when an application requests any available user port from the system. You could increase this in the Windows Registry, by adding the MaxUserPort key in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
.
For example:
reg.exe
add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
/v MaxUserPort
/t REG_DWORD
/d 0x000067c0
Code language: PowerShell (powershell)
This sets an value 0x000067c0
(26560) for MaxUserPort in the registry. A reboot is required to take this into effect.
Starting from Windows Server 2008 you can use netsh.exe
to configure a Dynamic Port Range.
Dynamic Port range
On Windows 2008 and 2012 we use the Network Shell (netsh
) to determine a dynamic port range. Its default setting is (as shown above):
C:\Users\Jan Reilink> netsh int ipv4 show dynamicportrange tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
Code language: PowerShell (powershell)
You can increase this by -for example- roughly 9152 extra ephemeral ports:
netsh int ipv4 set dynamicportrange protocol=tcp startport=40000 numberofports=25536 store=persistent
Code language: PowerShell (powershell)
Again, a reboot is required to take this in effect.
TCPTimedWaitDelay
The registry value TCPTimedWaitDelay
in Windows Server 2012 determines how long a closed port waits until the closed port can be reused. This defaults to 240 seconds and can be decreased to 30 seconds. The TcpTimedWaitDelay DWORD (32-bit) Value name is also found under HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
. As is MaxUserPort mentioned above.
Set it’s value to 3c hexadecimal for a 60 second TIME_WAIT window. Again an example:
reg.exe
add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
/v TCPTimedWaitDelay
/t REG_DWORD
/d 0x0000003c
Code language: PowerShell (powershell)
Bonus tip: convert hexadecimal values to decimal in PoweShell:
PS C:\Users\Jan Reilink> [uint32]"0x000067c0"
26560
PS C:\Users\Jan Reilink> [uint32]"0x3c"
60
Code language: PowerShell (powershell)
Easy, right? :)
Disable ECN Capability in Windows Server 2012
If you are on Windows Server 2012, you must not forget to disable explicit congestion notification (ECN, or ECN Capability). This really slows down outbound connections to some outdated, or faulty, network equipment.
Disabling ECN Capability can improve your outbound connection speed.
TCP Chimney Offload
TCP Chimney Offload is a networking technology that helps transfer the workload from the CPU to a network adapter during network data transfer. In Windows Server, TCP Chimney Offload enables the Windows networking subsystem to offload the processing of a TCP/IP connection to a network adapter that includes special support for TCP/IP offload processing.
TCP Chimney Offload is available in all versions of Windows Server 2008 and 2012. Both TCP/IPv4 connections and TCP/IPv6 connections can be offloaded if the network adapter supports this feature.
Configure TCP Chimney Offload in the operating system
netsh int tcp set global chimney=enabled
Code language: JavaScript (javascript)
In some rare circumstances, enabling TCP Chimney Offload might degrade performance. Maybe due to bad network interface card (NIC) firmware or drivers. Then you can disable TCP Chimney Offload:
netsh int tcp set global chimney=disabled
Code language: JavaScript (javascript)
Conclusion tuning (older) Windows Server TCP/IP stack and IIS for high performance websites and high volume of web requests
Out of the box, Windows Server and IIS are pretty optimized for high performance networking nowadays. See for example the default availability of HTTP/3 in Windows Server 2022. On older Windows versions however, you may need to make some configuration changes and tweaks to make Windows handle more network connections. But as always, measure first, make a change and measure again. Otherwise you don’t know if a change made an improvement.
And don’t forget this article was first written for Windows Server 2003, 2008 (R2) and Windows Server 2012.
Cheers!
Show Your Support

If you want to step in to help me cover the costs for running this website, that would be awesome. Just use this link to donate a cup of coffee ☕($10 USD or €10 EUR for example). And please share the love and help others make use of this website. Thank you very much! <3 ❤️