Introduction to Network Load Balancing on Windows Server 2019

Network Load Balancing (NLB) is a built-in Windows Server 2019 feature that distributes incoming TCP/IP traffic across multiple servers to improve scalability and availability for stateless applications. NLB is commonly used for web server farms, Remote Desktop Session Host farms, VPN gateways, and Terminal Services. Unlike hardware load balancers, NLB is software-based and operates at the network layer, making it simple to deploy without additional hardware costs.

NLB works by assigning a virtual IP address (VIP) to the cluster that all nodes share. All nodes receive every incoming packet, and NLB uses a deterministic algorithm to decide which node should handle each connection. NLB in Windows Server 2019 supports up to 32 nodes and is suitable for stateless HTTP workloads, though for stateful applications you must configure session affinity (also called sticky sessions).

Installing the NLB Feature

Install the NLB feature on all servers that will participate in the NLB cluster:

Install-WindowsFeature -Name NLB -IncludeManagementTools

This installs the NLB Manager (nlbmgr.exe) and the NLB PowerShell module. Verify the installation:

Get-WindowsFeature -Name NLB

Repeat the installation on every node that will be in the NLB cluster.

Creating the NLB Cluster

Create the NLB cluster on the first host. You need to specify the virtual IP address (the shared address clients will use), the subnet mask, and the full internet name (DNS name) clients will use to access the cluster:

New-NlbCluster -InterfaceName "Production NIC" -ClusterName "WebFarm" -ClusterPrimaryIP 192.168.1.200 -SubnetMask 255.255.255.0 -OperationMode Multicast

NLB supports three operation modes: Unicast (all nodes share the cluster MAC address, best for single NIC servers), Multicast (each node retains its own MAC, recommended for most deployments), and IGMP Multicast (multicast with IGMP support for switches that understand multicast groups). Multicast is the most compatible mode for most environments.

Verify the cluster was created:

Get-NlbCluster

Adding Nodes to the NLB Cluster

From the first node, add the remaining servers to the cluster:

Add-NlbClusterNode -HostName "WebServer02" -InterfaceName "Production NIC" -NewNodeInterface "Production NIC"

Add the third node:

Add-NlbClusterNode -HostName "WebServer03" -InterfaceName "Production NIC" -NewNodeInterface "Production NIC"

Verify all nodes are part of the cluster:

Get-NlbClusterNode

All nodes should show a status of “Converged” once they have joined the cluster and synchronised.

Configuring Port Rules

NLB port rules define which TCP/UDP ports are load-balanced and the affinity mode. By default, a port rule covering all ports (0-65535) is created. For a web server farm, create specific rules for HTTP and HTTPS:

# Remove the default all-ports rule
Get-NlbClusterPortRule | Remove-NlbClusterPortRule

# Create HTTP rule with no affinity (pure load balancing)
Add-NlbClusterPortRule -Protocol Tcp -StartPort 80 -EndPort 80 -Affinity None -LoadBalancingAlgorithm Equal

# Create HTTPS rule with single affinity (sticky sessions by IP)
Add-NlbClusterPortRule -Protocol Tcp -StartPort 443 -EndPort 443 -Affinity Single -LoadBalancingAlgorithm Equal

The Affinity parameter controls session stickiness: None (no stickiness), Single (client IP affinity — same client always goes to same node), or Network (subnet-level affinity).

Configuring Load Balancing Weights

If your servers have different capacities, assign different load weights so more powerful servers handle more traffic:

# Set WebServer01 to handle 50% of traffic
Set-NlbClusterNodePortRule -HostName "WebServer01" -LoadWeight 50

# Set WebServer02 to handle 30%
Set-NlbClusterNodePortRule -HostName "WebServer02" -LoadWeight 30

# Set WebServer03 to handle 20%
Set-NlbClusterNodePortRule -HostName "WebServer03" -LoadWeight 20

Managing NLB Cluster Operations

Stop a node from accepting new connections (drain stop — completes existing sessions before going offline):

Stop-NlbClusterNode -HostName "WebServer02" -Drain

Bring a node back online:

Start-NlbClusterNode -HostName "WebServer02"

Suspend a node immediately (drops existing connections):

Suspend-NlbClusterNode -HostName "WebServer02"

Check current NLB cluster status:

Get-NlbClusterNode | Select Name, Status, StatusCode

View port rules currently in effect:

Get-NlbClusterPortRule | Select StartPort, EndPort, Protocol, Affinity, LoadWeight

For production web farms, pair NLB with a health check mechanism. Because NLB does not natively perform application-layer health checks, use a monitoring script that drains and removes an unhealthy node from the cluster automatically when the application stops responding to health probes.