Remote Desktop Protocol can feel sluggish with default settings, especially for graphically demanding applications. Here's how to optimise RDP for the best user experience.
Direct RDP vs Azure Virtual Desktop
For single-VM scenarios, direct RDP often performs better than AVD:
- Direct RDP: Client → VM (single hop)
- AVD: Client → Gateway → Session Host (multiple hops)
If you don't need AVD's features (pooled desktops, RemoteApp, multi-session), direct RDP is simpler and faster.
Server-Side Optimisations
Enable UDP Transport
RDP over UDP significantly improves performance on lossy networks:
# Enable UDP transport
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
-Name "SelectTransport" -Value 0 -Type DWord
# 0 = UDP and TCP (default, best)
# 1 = TCP only
# 2 = UDP only
GPU Acceleration
For VMs with GPU (like NV-series), enable RemoteFX:
# Enable hardware graphics adapter
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
-Name "bEnumerateHWBeforeSW" -Value 1 -Type DWord
# Use hardware default graphics adapter
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
-Name "AVC444ModePreferred" -Value 1 -Type DWord
# Enable H.264/AVC hardware encoding
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
-Name "AVCHardwareEncodePreferred" -Value 1 -Type DWord
Frame Rate and Compression
# Maximum frame rate (default 30, max 60)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations" `
-Name "DWMFRAMEINTERVAL" -Value 15 -Type DWord
# Value is in milliseconds: 15ms = ~66fps
# Visual quality for moving images
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
-Name "VisualQualityPolicy" -Value 2 -Type DWord
# 0 = Low, 1 = Medium, 2 = High
Client-Side Settings
Windows Remote Desktop Client
Use the modern Remote Desktop app from the Microsoft Store - it supports:
- UDP transport
- H.264/AVC 444 graphics mode
- Better touch/pen input
RDP File Settings
Create an optimised .rdp file:
full address:s:vm.example.com:3389
use multimon:i:1
videoplaybackmode:i:1
enablecredsspsupport:i:1
authentication level:i:2
audiocapturemode:i:1
networkautodetect:i:0
bandwidthautodetect:i:0
connection type:i:6
compression:i:1
Key settings:
connection type:i:6- LAN (assumes good connection)networkautodetect:i:0- Disable auto-detect, use specified settingsvideoplaybackmode:i:1- Optimized video streaming
Network Configuration
Azure NSG Rules
Ensure UDP 3389 is allowed:
resource "azurerm_network_security_rule" "rdp_udp" {
name = "RDP-UDP"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Udp"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "YOUR_IP/32"
destination_address_prefix = "*"
resource_group_name = azurerm_resource_group.this.name
network_security_group_name = azurerm_network_security_group.vm.name
}
Disable Window Auto-Tuning (if having issues)
Sometimes auto-tuning causes problems:
# Check current setting
netsh interface tcp show global
# Disable if needed
netsh interface tcp set global autotuninglevel=disabled
Monitoring Performance
Check Graphics Mode
# Query graphics mode
qwinsta /vm
# Check RemoteFX status
Get-WmiObject -Namespace "root\cimv2\TerminalServices" -Class Win32_TSGeneralSetting
Measure Latency
# In-session latency check
$stats = Get-WmiObject -Namespace "root\cimv2\TerminalServices" `
-Class Win32_PerfFormattedData_TermService_TerminalServicesSession
$stats | Select-Object Name,
@{N='RTT';E={$_.OutputTimeBetweenPDUs}}
Azure-Specific Tips
Proximity Placement Groups
For lowest latency to on-premises:
resource "azurerm_proximity_placement_group" "rdp" {
name = "ppg-rdp-vms"
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
}
Accelerated Networking
Always enable on supported VM sizes:
resource "azurerm_network_interface" "vm" {
name = "nic-rdp-vm"
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
enable_accelerated_networking = true # Important!
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.vms.id
private_ip_address_allocation = "Dynamic"
}
}
Need help optimising remote desktop performance? Get in touch - we help organisations build responsive remote work solutions.