Applicable to Pure supported Windows Server versions.
This Best Practice has not yet been tested with bonded (aka "teamed") network interfaces.
The Windows operating system incorporates a setting for TCPIP called the Delayed Acknowledgement feature. By changing the default settings, you could possibly reduce the amount of overall network latency when using iSCSI connections. Along with this setting, the registry entry that enables Nagle should also be set to disabled. These settings should be applied to only network interface instances that are used for iSCSI traffic. All iSCSI adapters should be set to the same settings. If the entries do not exist, they should be created.
Altering these settings may have a negative effect on other services and protocols used on the server. While this is a recommended practice, caution is given that the setting changes should be tested in your environment before altering a production system. Please consult official Microsoft documentation for more details.
Registry Keys
Subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<Interface GUID>
Entry: TcpAckFrequency
Value Type: REG_DWORD
Valid Range: 0-255
Default: 2
New Setting: 1
Subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<Interface GUID>
Entry: TcpNoDelay
Value Type: REG_DWORD
Valid Range: 0-1
Default: 0
New Setting: 1
This image illustrates the new settings.
The machine should be rebooted after making any of these registry changes.
PowerShell to Add or Change Registry Keys
This is a snippet of a example script that will enumerate all of the network adapters on a system and require the user to enter the adapter name(s) they wish to apply the settings to. This script is not all-inclusive to every environment and should be tested thoroughly before running in production.
The individual script is available in the Pure PowerShell Example Scripts repository. The Everpure PowerShell Toolkit also contains a cmdlet to perform this configuration. The machine should be rebooted after making any of these registry changes.
<# Script to disable Nagle (TcpNoDelay) and TcpAckFrequency on a per adapter basis.#>
$AdapterNames = @()
Write-Host "All available adapters: "
Write-Host " "
$adapters = Get-NetAdapter | Sort-Object Name | Format-Table -Property "Name", "InterfaceDescription", "MacAddress", "Status"
$adapters
Write-Host " "
$AdapterNames = Read-Host "Please enter all iSCSI adapter names to be tested. Use a comma to seperate the names - ie. NIC1,NIC2,NIC3"
$AdapterNames = $AdapterNames.Split(',')
Write-Host " "
Write-Host "Adapter names being configured: "
$AdapterNames
Write-Host "==============================="
foreach ($adapter in $AdapterNames) {
$adapterGuid = (Get-NetAdapterAdvancedProperty -Name $adapter -RegistryKeyword "NetCfgInstanceId" -AllProperties).RegistryValue
$RegKeyPath = "HKLM:\system\currentcontrolset\services\tcpip\parameters\interfaces\$adapterGuid\"
$TAFRegKey = "TcpAckFrequency"
$TNDRegKey = "TcpNoDelay"
## TcpAckFrequency
if ((Get-ItemProperty $RegkeyPath).$TAFRegKey -eq "1") {
Write-Host ": TcpAckFrequency is set to disabled (1). No action required."
}
if (-not (Get-ItemProperty $RegkeyPath $TAFRegKey -ErrorAction SilentlyContinue)) {
Write-Host ": TcpAckFrequency key does not exist."
Write-Host "REQUIRED ACTION: Set the TcpAckFrequency registry value to 1 for $adapter ?" -NoNewline
$resp = Read-Host -Prompt "Y/N?"
if ($resp.ToUpper() -eq 'Y') {
Write-Host "Creating Registry key and setting to disabled..."
New-ItemProperty -Path $RegKeyPath -Name 'TcpAckFrequency' -Value '1' -PropertyType DWORD -Force -ErrorAction SilentlyContinue
}
else {
Write-Host "WARNING" -ForegroundColor Yellow -NoNewline
Write-Host ": TcpAckFrequency registry key exists but is enabled. Changing to disabled."
Set-ItemProperty -Path $RegKeyPath -Name 'TcpAckFrequency' -Value '1' -Type DWORD -Force -ErrorAction SilentlyContinue
}
}
if ($resp.ToUpper() -eq 'N') {
Write-Host "ABORTED" -ForegroundColor Yellow -NoNewline
Write-Host ": Registry key not created or altered by request of user."
}
## TcpNoDelay
if ((Get-ItemProperty $RegkeyPath).$TNDRegKey -eq "1") {
Write-Host ": TcpNoDelay (Nagle) is set to disabled (1). No action required."
}
if (-not (Get-ItemProperty $RegkeyPath $TNDRegKey -ErrorAction SilentlyContinue)) {
Write-Host "REQUIRED ACTION: Set the TcpNodelay (Nagle) registry value to 1 for $adapter ?" -NoNewline
$resp = Read-Host -Prompt "Y/N?"
if ($resp.ToUpper() -eq 'Y') {
Write-Host "TcpNoDelay registry key does not exist. Creating..."
New-ItemProperty -Path $RegKeyPath -Name 'TcpNoDelay' -Value '1' -PropertyType DWORD -Force -ErrorAction SilentlyContinue
}
else {
Write-Host "WARNING" -ForegroundColor Yellow -NoNewline
Write-Host ": TcpNoDelay registry key exists. Setting value to 1."
Set-ItemProperty -Path $RegKeyPath -Name 'TcpNoDelay' -Value '1' -Type DWORD -Force -ErrorAction SilentlyContinue
}
}
if ($resp.ToUpper() -eq 'N') {
Write-Host "ABORTED" -ForegroundColor Yellow -NoNewline
Write-Host ": TcpNoDelay registry key not created or altered by request of user."
}
}