Disabling Delayed ACK and Nagle

Microsoft Platform Guide

Audience
Public
Source Type
Documentation
Note:

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.

Note:

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."
            }
        }