How to Set Up Windows Server 2019 SR-IOV

Single Root I/O Virtualization (SR-IOV) is a PCI-SIG specification that allows a single physical PCIe network adapter to present multiple virtual functions (VFs) directly to virtual machines, bypassing the Hyper-V virtual switch and the software network stack. This provides near-native network performance in VMs with ultra-low latency and minimal CPU overhead. Windows Server 2019 Hyper-V supports SR-IOV for appropriately equipped hardware, and this guide covers enabling SR-IOV from the BIOS level through to the VM configuration.

Hardware and BIOS Requirements

SR-IOV requires several hardware prerequisites: the server BIOS must have SR-IOV and Intel VT-d (or AMD-Vi) enabled; the physical NIC must support SR-IOV and have SR-IOV-compatible drivers; and the PCIe slot must support ARI (Alternative Routing Interpretation) forwarding. Common SR-IOV-capable adapters include Intel X710/XL710, Mellanox ConnectX-4 and later, Broadcom BCM57810, and Chelsio T5/T6 series.

# Check if SR-IOV is available on physical adapters
Get-NetAdapterSriov | Select-Object Name, Enabled, VFsAllocated, NumVFs, VlanID

# Check if the adapter supports SR-IOV
Get-NetAdapter | ForEach-Object {
    $sriov = $_ | Get-NetAdapterSriov -ErrorAction SilentlyContinue
    if ($sriov -ne $null) {
        [PSCustomObject]@{
            Name = $_.Name
            Description = $_.InterfaceDescription
            SriovEnabled = $sriov.Enabled
            VFsTotal = $sriov.NumVFs
            VFsAllocated = $sriov.VFsAllocated
        }
    }
} | Format-Table -AutoSize

Enabling SR-IOV on the Physical Adapter

# Enable SR-IOV on a specific adapter
Enable-NetAdapterSriov -Name "SLOT 4 Port 1"

# Verify SR-IOV is enabled
Get-NetAdapterSriov -Name "SLOT 4 Port 1" | Select-Object Name, Enabled, NumVFs

# Set the number of virtual functions (VFs) available
# This varies by adapter - consult adapter documentation
Set-NetAdapterSriov -Name "SLOT 4 Port 1" -NumVFs 32

# Verify configuration
Get-NetAdapterSriov -Name "SLOT 4 Port 1"

Creating an SR-IOV Enabled Hyper-V Virtual Switch

# Create a virtual switch with SR-IOV enabled
New-VMSwitch -Name "SriovSwitch" `
  -NetAdapterName "SLOT 4 Port 1" `
  -EnableIov $true `
  -AllowManagementOS $true

# Verify the switch has IOV enabled
Get-VMSwitch -Name "SriovSwitch" | Select-Object Name, IovEnabled, IovSupport, IovSupportReasons

# If IovEnabled is False and IovSupportReasons is populated, review the reasons
Get-VMSwitch -Name "SriovSwitch" | Select-Object -ExpandProperty IovSupportReasons

Enabling SR-IOV on a Virtual Machine

# Add a network adapter with SR-IOV enabled to an existing VM
# The VM must be powered off first
Stop-VM -Name "VM-HighPerf-01" -Force

# Add VM network adapter with SR-IOV enabled
Add-VMNetworkAdapter -VMName "VM-HighPerf-01" `
  -SwitchName "SriovSwitch" `
  -Name "SRIOV-NIC"

# Enable SR-IOV on the adapter
Set-VMNetworkAdapter -VMName "VM-HighPerf-01" `
  -Name "SRIOV-NIC" `
  -IovWeight 100  # 0 = disabled, 1-100 = enabled with weight

# Start the VM
Start-VM -Name "VM-HighPerf-01"

# Verify SR-IOV is in use inside the VM
# Run inside the VM:
Get-NetAdapterSriov

Configuring SR-IOV Queue Pairs and Interrupt Moderation

# Configure the number of queue pairs per VF (more queues = more parallelism)
Set-VMNetworkAdapterIsolation -VMName "VM-HighPerf-01" `
  -VMNetworkAdapterName "SRIOV-NIC" `
  -IsolationMode None

# Set IOV queue pairs (adapter-specific, consult documentation)
Set-VMNetworkAdapter -VMName "VM-HighPerf-01" `
  -Name "SRIOV-NIC" `
  -IovQueuePairsRequested 4

# Configure interrupt moderation on the physical adapter
Set-NetAdapterAdvancedProperty -Name "SLOT 4 Port 1" `
  -DisplayName "Interrupt Moderation" `
  -DisplayValue "Enabled"

Set-NetAdapterAdvancedProperty -Name "SLOT 4 Port 1" `
  -DisplayName "Interrupt Moderation Rate" `
  -DisplayValue "Adaptive"

Monitoring SR-IOV Performance

# Check VF allocation status
Get-NetAdapterSriov | Select-Object Name, VFsAllocated, NumVFs

# View per-VM VF allocation
Get-VMNetworkAdapter -VMName * | Where-Object { $_.IovWeight -gt 0 } |
  Select-Object VMName, Name, IovWeight, IovUsage, SwitchName

# Performance counters for SR-IOV (check inside the VM)
# Inside VM:
Get-Counter -Counter "Network Interface(*)Bytes Total/sec" |
  Select-Object -ExpandProperty CounterSamples |
  Where-Object { $_.InstanceName -ne "_total" } |
  Select-Object InstanceName, CookedValue

# CPU usage comparison: SR-IOV vs software switch
# With SR-IOV, CPU usage for high-throughput network workloads should be near zero

SR-IOV and Live Migration Considerations

# SR-IOV VMs can live migrate but fall back to software switch during migration
# Enable fallback to ensure migration succeeds
Set-VMNetworkAdapter -VMName "VM-HighPerf-01" `
  -Name "SRIOV-NIC" `
  -AllowTeaming Off

# Check if all destination hosts have SR-IOV with matching configuration
$destinationHosts = @("HyperV-Host-02","HyperV-Host-03")
foreach ($host in $destinationHosts) {
    $sriov = Invoke-Command -ComputerName $host -ScriptBlock {
        Get-NetAdapterSriov | Select-Object Name, Enabled, NumVFs
    }
    Write-Output "Host: $host"
    $sriov | Format-Table
}

# Perform live migration with SR-IOV VM
Move-VM -Name "VM-HighPerf-01" `
  -DestinationHost "HyperV-Host-02" `
  -IncludeStorage `
  -DestinationStoragePath "E:VMs"

SR-IOV provides the highest possible network performance for VMs that handle large amounts of traffic, such as network virtual appliances, high-throughput database VMs, or latency-sensitive financial applications. The trade-off is reduced flexibility — SR-IOV VMs cannot use all Hyper-V networking features like port mirroring, VM network isolation, or QoS policies on the virtual switch. Evaluate whether the performance gain justifies these limitations for each workload before enabling SR-IOV in production.