
Azure Load BalancerAuthorCloudBrum editorial teamLast reviewedReading time~12 minLevelBeginner to advanced
Microsoft Azure · Networking · Layer 4 load balancer for TCP and UDP
Azure Load Balancer is the layer 4 balancer of Azure: it takes TCP and UDP connections that arrive at one address and hands each to a healthy server in a backend pool. It is fast, zone-aware and sits inside the Azure network, so it suits virtual machine scale sets, databases, game servers and the back half of a web tier. It doesn’t read HTTP, so web routing, TLS offload and a web firewall belong to Application Gateway or Front Door. The thing that catches most teams out is the other direction, outbound connections and the SNAT ports they use.
On this page (17 sections)
Mind map: Azure Load Balancer at a glance
Free to share. The downloaded image includes the CloudBrum link.
Key features (summary)
- Layer 4 distributionFor each new connection the load balancer hashes the source and destination address, the ports and the protocol, and picks a backend. All packets of that flow then go to the same server. Source IP persistence is available for clients that need to return to one server.
- Health probesA TCP, HTTP or HTTPS probe tests each backend. After the set number of failures the server gets no new connections until the probe passes again. Existing connections keep going on a TCP flow unless the server resets them.
- Public or internalA public load balancer fronts the internet with a public IP. An internal one has a private address inside the virtual network and balances between tiers, such as web to database.
- Zone redundancyIn regions with availability zones, a Standard frontend can be zone-redundant and keep working if a zone fails, or pinned to one zone for placement control.
- Outbound connectivityServers in the pool reach the internet through SNAT ports. Outbound rules and a NAT gateway give you control over which addresses and how many ports they get.
- Rules and portsA rule maps a frontend port to a backend port. HA ports on an internal load balancer balance every port at once, and floating IP supports clustered databases. Inbound NAT rules reach one specific server.
- Global tierA global load balancer has one anycast IP, and spreads TCP and UDP traffic across regional Standard load balancers in different regions, with failover between them.
- Gateway Load BalancerChains third-party virtual appliances such as firewalls into the traffic path transparently, so the original source and destination are kept and the application needn’t change.
Basic concepts
- Frontend IP configuration
- The address, public or private, that clients connect to. A load balancer can have several.
- Backend pool
- The set of network interfaces or IP addresses that receive the traffic. Virtual machines and scale set instances join it.
- Health probe
- A test that the load balancer runs against each backend, from the address 168.63.129.16. A backend that fails its probes receives no new connections.
- Load balancing rule
- Maps a frontend IP and port to a backend pool and port, with a probe, a distribution mode and an idle timeout.
- Session persistence
- Controls whether packets from the same client go to the same server: none (five-tuple hash), client IP, or client IP and protocol.
- Inbound NAT rule
- Forwards a frontend port to a single backend server and port, for example to reach one machine over SSH. These rules aren’t counted for billing.
- Outbound rule
- Defines which frontend addresses the backend uses for outbound connections and how many SNAT ports each server gets.
- SNAT and SNAT ports
- Source network address translation lets many private servers share a few public addresses. Each outbound connection to the same destination needs its own port, and the supply is limited.
- Standard and Basic SKU
- Standard is the production SKU, with zones, a service-level agreement and secure-by-default behaviour. The Basic SKU was retired on 30 September 2025.
- Gateway SKU
- A load balancer type used to insert virtual appliances in front of Standard frontends or network interfaces.
- Global tier
- A tier of Standard that spreads traffic across load balancers in several regions through one anycast address.
- HA ports
- An internal load balancer rule that balances all TCP and UDP ports, used for virtual appliances.
- TCP reset on idle
- An option that sends a reset to both ends when an idle connection times out, so applications learn about it at once instead of hanging.
How to create & configure it
Create a Standard load balancer for two web servers with the Azure CLI
- Check that layer 4 is what you needUse Azure Load Balancer for TCP and UDP traffic and for tiers inside a network. If you need URL routing, TLS offload or a WAF for web traffic, use Application Gateway or Front Door, and put this in front of other services.
- Plan the network and the security groupCreate the virtual network and the network security group first. A Standard load balancer blocks inbound traffic until a rule in the group allows it.
- Create a zone-redundant Standard public IPUse a Standard SKU public IP with all three zones, so the frontend survives a zone failure.
- Create the load balancer, a front end and a poolKeep names clear, since probes, rules and pools reference each other by name.
- Add a health probeUse HTTP against a real path such as /health. A TCP probe only shows that the port is open, not that the application works.
- Add the ruleMap the front end port to the back end port, attach the probe, set the idle timeout and turn on TCP reset.
- Plan outbound trafficAdd a NAT gateway to the subnet or define outbound rules, so servers don’t rely on the limited default SNAT ports.
- Add the servers to the poolCreate network interfaces that join the pool, then attach virtual machines, or point a scale set at the pool.
- Check the metricsDipAvailability shows the probe result per server, and VipAvailability shows whether the front end answers. Watch SNAT port use as well.
Tip: Microsoft is moving new virtual networks to private subnets, which have no default outbound access, so servers behind a load balancer need an explicit way out: a NAT gateway, an outbound rule or a public IP of their own. Decide this at design time, since a missing outbound path shows up as updates and package downloads that hang. See the code references for the same setup as Terraform.
Common issues after configuration
| Symptom | Likely cause | What to check / fix |
|---|---|---|
| The front end doesn’t answer after creation | A Standard load balancer is closed to inbound traffic by default: no security group rule allows it, the NICs aren’t in the pool, or the server’s own firewall blocks the port | Add an inbound allow rule to the network security group, confirm pool membership, and check the operating system firewall. |
| Every backend is marked unhealthy | The probe port or path is wrong, the application isn’t listening, or a firewall or a deny rule blocks the probe source 168.63.129.16 | Test the probe path on the server, and allow the AzureLoadBalancer service tag in the network security group and the OS firewall. |
| A server behind an internal load balancer can’t reach the front end | A backend server can’t use its own internal load balancer’s frontend address, because the flow returns to the same machine | Use a different tier or a separate client machine for the call, or a different front end design such as DNS to the servers. |
| Outbound connections fail now and then | SNAT ports ran out: many connections to the same destination use up the ports available to each server | Add a NAT gateway or an outbound rule with more addresses, reuse connections, and watch the SNAT metrics. |
| Long-lived connections are cut after a few minutes | The default idle timeout is 4 minutes, and idle flows are dropped | Send keep-alives, raise the idle timeout on the rule (up to 100 minutes on Standard) and turn on TCP reset. |
| Traffic is uneven across servers | The five-tuple hash spreads connections, not load, so a few heavy or long-lived connections or a small number of clients skew it | Spread clients, shorten connections where you can, or use client IP persistence only when you need it. |
| A Basic load balancer stopped working or can’t be changed | The Basic SKU was retired on 30 September 2025 | Upgrade to Standard with Microsoft’s migration tooling, and use Standard public IPs. |
| SKU mismatch when attaching a public IP | A Standard load balancer needs Standard SKU public IPs, and Basic ones don’t mix | Create the public IP as Standard and static. |
| Probes flap between healthy and unhealthy | The interval is short, the threshold is low, or the application is slow under load | Raise the threshold and the interval a little, and make the probe path cheap and independent of slow dependencies. |
| Updates and downloads hang on new servers | No outbound path exists, because default outbound access isn’t available in the subnet | Attach a NAT gateway to the subnet, add an outbound rule, or give the servers a public IP. |
| The bill is higher than expected | More rules than you need, a lot of data processed, public IPs and a NAT gateway that each cost separately | Merge rules, delete unused load balancers and IPs, and review data processed per load balancer. |
Use cases: when and where to use it
Good fit
- TCP or UDP services that need to be spread across several servers
- The internal tier of an application, such as web servers calling a database cluster
- Virtual machine scale sets that need a stable front end
- Chaining firewalls and other virtual appliances into traffic (Gateway Load Balancer)
- Services that need fast, zone-aware balancing without a proxy in the middle
- Spreading TCP or UDP traffic across regions with one anycast IP (global tier)
Consider something else
- HTTP(S) routing, TLS offload and a WAF inside a region → Azure Application Gateway
- A global HTTP(S) entry point with caching and WAF → Azure Front Door
- DNS-based routing for any protocol → Azure Traffic Manager
- Outbound-only internet access with fixed addresses → Azure NAT Gateway
- A fully managed platform with its own front end → Azure App Service
- The same job on other clouds → compare Elastic Load Balancing and Cloud Load Balancing
Pros: why consider it?
Why teams choose it
- Fast and low-latency, with no proxy for traffic to pass through
- Zone-redundant frontends and a service-level agreement on Standard
- Works for any TCP or UDP application
- Internal and public load balancers use the same building blocks
- Secure by default: closed until a security group opens it
- Gateway and global tiers extend it to appliances and several regions
Trade-offs to weigh
- No understanding of HTTP: no URL routing, TLS offload or WAF
- Outbound SNAT port limits catch teams out without a NAT gateway or outbound rules
- The five-tuple hash balances connections, not load
- Health probe design is on you, and a shallow probe hides real faults
- A backend can’t call its own internal front end
- Several billed parts: rules, data processed, public IPs and NAT gateways
Common threats, vulnerabilities & risks
| Risk | Severity | Why it matters | Mitigation |
|---|---|---|---|
| Network security group rules that are too wide | High | Opening a port to the whole internet exposes every server in the pool. | Allow only the ports the service needs, limit source ranges where you can, and review rules regularly. |
| Management ports reachable through the load balancer | High | Inbound NAT rules for SSH or RDP put those ports on a public address. | Use Azure Bastion or a VPN instead, and remove inbound NAT rules for administration. |
| Still running on the retired Basic SKU | High | The SKU is retired, has no zone support and no service-level agreement, and was open to the internet by default. | Inventory Basic load balancers and public IPs, and migrate to Standard now. |
| A shallow health probe | Medium | A TCP probe says the port is open even if the application is broken, so users get errors from servers that look healthy. | Use an HTTP or HTTPS probe on a path that checks what matters. |
| SNAT port exhaustion | Medium | Outbound connections fail under load, and the cause is hard to see without metrics. | Use a NAT gateway or outbound rules, pool connections and alert on SNAT usage. |
| A single zone or region | Medium | A zone or regional outage takes the service down. | Use zone-redundant frontends and backends across zones, and the global tier or DNS routing for regional failover. |
| No logging or metrics alerts | Medium | Probe failures and SNAT pressure go unnoticed until customers complain. | Alert on DipAvailability, VipAvailability and SNAT metrics, and send diagnostics to Log Analytics. |
| Default outbound access assumed | Low–Med | New virtual networks are moving to private subnets without default outbound access. | Plan explicit outbound with a NAT gateway or outbound rules. |
| Orphaned load balancers and public IPs | Low–Med | Unused ones keep billing and widen the attack surface. | Tag with an owner and review monthly. |
Performance optimisation
- Spread backends across availability zones, and use zone-redundant frontends so a zone failure doesn’t remove the entry point.
- Use HTTP probes with a cheap path, and tune the interval and threshold so failures are detected quickly without flapping.
- Turn on TCP reset so that applications learn about dropped idle connections at once.
- Set the idle timeout to match the application, and send keep-alives for long-lived connections.
- Use a NAT gateway for outbound traffic, and reuse connections to avoid burning SNAT ports.
- Keep traffic in the same zone and region where you can, to cut latency and data transfer cost.
- Use client IP persistence only for applications that need it, since it can skew the balance.
- Test with realistic connection counts, because the hash balances connections and not load.
Reduce monthly cost
FinOps is the habit of managing cloud spend together with engineering. These are the FinOps checks that matter most for Azure Load Balancer.
- Keep the number of rules to what you need, since rules are billed by the hour.
- Remember that inbound NAT rules aren’t counted, but they expose ports, so use them sparingly.
- Delete unused load balancers, public IPs and NAT gateways.
- Compare a NAT gateway with outbound rules for your traffic, since each has its own charges.
- Watch data processed, and keep chatty traffic inside a zone where the design allows.
- Use the global tier only when you need cross-region TCP or UDP, since it adds a layer.
- Choose an internal load balancer for private traffic, which avoids public IP charges.
- Use Application Gateway or Front Door for web traffic instead of building HTTP features on top of a layer 4 balancer.
- Tag resources by team, and review cost by resource monthly.
- Add a budget alert on the resource group.
Figures here come from Microsoft's pricing page structure and documentation, read in October 2026. The page's exact rates differ by region and currency, so confirm them on the live page (see Pricing).
Security optimisation
- Allow only the ports and source ranges that the service needs in the network security group, and review them regularly.
- Use internal load balancers for private tiers, and keep backend servers without public IPs.
- Don’t publish SSH or RDP through inbound NAT rules. Use Azure Bastion or a VPN.
- Allow the AzureLoadBalancer service tag for probes, so a deny rule doesn’t take servers out of the pool.
- Use NAT gateways for outbound traffic, with fixed addresses that partners can allow-list.
- Send diagnostic logs and metrics to Log Analytics, and alert on probe and SNAT problems.
- Use Azure Policy to deny Basic SKU resources and public IPs where they shouldn’t exist.
- Restrict who can change load balancers and their rules with Azure RBAC, and add resource locks.
- Put a WAF-capable service (Application Gateway or Front Door) in front of web traffic.
- Review Microsoft Defender for Cloud recommendations for network exposure.
Governance & compliance
Guardrails
- A shared Bicep or Terraform module for load balancers that creates Standard SKU, zone-redundant frontends, HTTP probes, TCP reset, diagnostics and tags
- Azure Policy that denies the Basic SKU, public IPs on selected subnets and load balancers without diagnostic settings
- A naming standard for frontends, pools, probes and rules, so references stay readable
- A review step for any inbound NAT rule or open management port
Continuous checks (Azure Policy, Defender for Cloud and your own scripts)
- A scheduled script that lists load balancers on the Basic SKU, with TCP-only probes, with SNAT left on and no outbound rule, or without TCP reset (the C# tab does this)
- Azure Policy compliance for SKU, diagnostics and public exposure
- Alerts on DipAvailability, VipAvailability and SNAT port use
- An activity log alert for changes to rules, probes and backend pools
- A monthly report of load balancers and public IPs by cost and owner
Azure Policy audits and enforces settings, Microsoft Defender for Cloud flags exposed endpoints, while the activity log and Azure Monitor hold changes and metrics, and the Microsoft Service Trust Portal holds compliance reports. Microsoft runs the load balancer platform. Rule and probe design, security group rules, outbound design and the health of your own servers are yours.
Reduce carbon footprint
- Delete idle load balancers, public IPs and NAT gateways.
- Keep traffic within a zone and region where the design allows, to shorten network paths.
- Right-size the scale set behind it with autoscale, so servers aren’t idle.
- Use internal frontends for private traffic.
- Deploy to a region with a cleaner power grid if data rules and latency allow it.
- Microsoft’s Emissions Impact Dashboard reports per subscription, with no separate figure for Load Balancer, so this page gives none.
Pricing
Purchase options
Standard load balancer Per rule hour, plus per GB
Billed per rule per hour and per GB processed. The billable count is the number of load balancing and outbound rules, with a first group of rules at one rate and extra rules at another. There is no hourly charge when no rules exist.
Inbound NAT rules Free
Inbound NAT rules are not counted in the rules total, though the ports they publish still need protecting.
Gateway and global tiers Gateway hours and data
The Gateway SKU bills for gateway and chain hours plus data processed. Traffic from a global load balancer to a regional one carries no additional data processing charge.
Related resources IPs, NAT gateway, transfer
Standard public IP addresses, a NAT gateway (by the hour and by data processed) and data transfer out of Azure are billed on their own.
What you actually pay for
- Load balancing and outbound rules, per hour
- Data processed, in both directions, per GB
- Standard public IP addresses
- A NAT gateway, by the hour and per GB processed
- Data transfer between zones and regions, and out to the internet
Microsoft lists the rule, data processing and gateway meters on its pricing page, and rates differ by region and currency. See the official Azure Load Balancer pricing page and the Azure pricing calculator.
Important code references
Two web servers behind a Standard load balancer: a network and security group, a zone-redundant public IP, an HTTP probe, a rule with TCP reset, a NAT gateway for outbound traffic, network interfaces that join the pool and two virtual machines. The CLI tab builds it and reads the probe and data path metrics; Terraform describes the same resources. The Python tab reads probe health per server and SNAT port pressure from Azure Monitor, and the C# tab audits load balancers for the Basic SKU, TCP-only probes, SNAT left on without outbound rules and missing TCP reset. Replace the names and the region with your own.
# Placeholders: replace the names and the region with your own.
RG=rg-lb-demo
LOC=centralindia
az group create --name $RG --location $LOC
# 1. A network, and a security group that lets web traffic in. A Standard load balancer is closed to inbound traffic until a
# security group allows it (the retired Basic SKU was open by default).
az network vnet create --resource-group $RG --name vnet-web --address-prefixes 10.20.0.0/16 --subnet-name web --subnet-prefixes 10.20.1.0/24
az network nsg create --resource-group $RG --name nsg-web
az network nsg rule create --resource-group $RG --nsg-name nsg-web --name allow-http --priority 100 --direction Inbound --access Allow \
--protocol Tcp --source-address-prefixes Internet --destination-port-ranges 80 8080
# 2. A zone-redundant Standard public IP and the load balancer with one front end and one backend pool.
az network public-ip create --resource-group $RG --name lb-ip --sku Standard --allocation-method Static --zone 1 2 3
az network lb create --resource-group $RG --name lb-web --sku Standard --public-ip-address lb-ip \
--frontend-ip-name front --backend-pool-name pool
# 3. A health probe that calls /health every 15 seconds, and a rule that sends port 80 to port 8080.
# A server leaves the rotation after two failed probes. TCP reset on idle tells both ends when a connection was dropped,
# and outbound SNAT is switched off on the rule because outbound traffic goes through a NAT gateway (step 4).
az network lb probe create --resource-group $RG --lb-name lb-web --name health --protocol Http --port 8080 --path /health \
--interval 15 --probe-threshold 2
az network lb rule create --resource-group $RG --lb-name lb-web --name web --protocol Tcp --frontend-port 80 --backend-port 8080 \
--frontend-ip-name front --backend-pool-name pool --probe-name health --idle-timeout 4 --enable-tcp-reset true --disable-outbound-snat true
# 4. Outbound traffic: a NAT gateway on the subnet gives the servers a fixed outbound address and plenty of ports.
az network public-ip create --resource-group $RG --name nat-ip --sku Standard --allocation-method Static
az network nat gateway create --resource-group $RG --name natgw --public-ip-addresses nat-ip --idle-timeout 10
az network vnet subnet update --resource-group $RG --vnet-name vnet-web --name web --nat-gateway natgw --network-security-group nsg-web
# 5. Two network interfaces that join the backend pool as they are created, and a server on each.
for N in 1 2; do
az network nic create --resource-group $RG --name web-$N-nic --vnet-name vnet-web --subnet web \
--lb-name lb-web --lb-address-pools pool
az vm create --resource-group $RG --name web-$N --image Ubuntu2204 --size Standard_B2s --admin-username azureuser \
--generate-ssh-keys --nics web-$N-nic --no-wait
done
# 6. Is each server answering its probe, and is the data path up? Both are metrics on the load balancer, split by backend address.
LB_ID=$(az network lb show --resource-group $RG --name lb-web --query id --output tsv)
az monitor metrics list --resource $LB_ID --metric DipAvailability --dimension BackendIPAddress --aggregation Average --interval PT5M --offset 1h
az monitor metrics list --resource $LB_ID --metric VipAvailability --aggregation Average --interval PT5M --offset 1h
# Placeholders: pass in your own location. The names below are examples.
variable "location" {
type = string
default = "centralindia"
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "lb" {
name = "rg-lb-demo"
location = var.location
}
resource "azurerm_virtual_network" "web" {
name = "vnet-web"
address_space = ["10.20.0.0/16"]
location = azurerm_resource_group.lb.location
resource_group_name = azurerm_resource_group.lb.name
}
resource "azurerm_subnet" "web" {
name = "web"
resource_group_name = azurerm_resource_group.lb.name
virtual_network_name = azurerm_virtual_network.web.name
address_prefixes = ["10.20.1.0/24"]
}
# A Standard load balancer is closed to inbound traffic until a security group allows it.
resource "azurerm_network_security_group" "web" {
name = "nsg-web"
location = azurerm_resource_group.lb.location
resource_group_name = azurerm_resource_group.lb.name
security_rule {
name = "allow-http"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_ranges = ["80", "8080"]
source_address_prefix = "Internet"
destination_address_prefix = "*"
}
}
resource "azurerm_subnet_network_security_group_association" "web" {
subnet_id = azurerm_subnet.web.id
network_security_group_id = azurerm_network_security_group.web.id
}
resource "azurerm_public_ip" "lb" {
name = "lb-ip"
location = azurerm_resource_group.lb.location
resource_group_name = azurerm_resource_group.lb.name
sku = "Standard"
allocation_method = "Static"
zones = ["1", "2", "3"]
}
resource "azurerm_lb" "web" {
name = "lb-web"
location = azurerm_resource_group.lb.location
resource_group_name = azurerm_resource_group.lb.name
sku = "Standard"
frontend_ip_configuration {
name = "front"
public_ip_address_id = azurerm_public_ip.lb.id
}
}
resource "azurerm_lb_backend_address_pool" "pool" {
loadbalancer_id = azurerm_lb.web.id
name = "pool"
}
resource "azurerm_lb_probe" "health" {
loadbalancer_id = azurerm_lb.web.id
name = "health"
protocol = "Http"
port = 8080
request_path = "/health"
interval_in_seconds = 15
probe_threshold = 2
}
resource "azurerm_lb_rule" "web" {
loadbalancer_id = azurerm_lb.web.id
name = "web"
protocol = "Tcp"
frontend_port = 80
backend_port = 8080
frontend_ip_configuration_name = "front"
backend_address_pool_ids = [azurerm_lb_backend_address_pool.pool.id]
probe_id = azurerm_lb_probe.health.id
idle_timeout_in_minutes = 4
enable_tcp_reset = true
disable_outbound_snat = true # outbound traffic goes through the NAT gateway below
}
# Outbound traffic: a NAT gateway gives the servers a fixed outbound address and plenty of ports.
resource "azurerm_public_ip" "nat" {
name = "nat-ip"
location = azurerm_resource_group.lb.location
resource_group_name = azurerm_resource_group.lb.name
sku = "Standard"
allocation_method = "Static"
}
resource "azurerm_nat_gateway" "web" {
name = "natgw"
location = azurerm_resource_group.lb.location
resource_group_name = azurerm_resource_group.lb.name
sku_name = "Standard"
idle_timeout_in_minutes = 10
}
resource "azurerm_nat_gateway_public_ip_association" "web" {
nat_gateway_id = azurerm_nat_gateway.web.id
public_ip_address_id = azurerm_public_ip.nat.id
}
resource "azurerm_subnet_nat_gateway_association" "web" {
subnet_id = azurerm_subnet.web.id
nat_gateway_id = azurerm_nat_gateway.web.id
}
# Two network interfaces that join the backend pool. Attach a virtual machine to each, or point a scale set at the pool.
resource "azurerm_network_interface" "web" {
count = 2
name = "web-${count.index + 1}-nic"
location = azurerm_resource_group.lb.location
resource_group_name = azurerm_resource_group.lb.name
ip_configuration {
name = "primary"
subnet_id = azurerm_subnet.web.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_network_interface_backend_address_pool_association" "web" {
count = 2
network_interface_id = azurerm_network_interface.web[count.index].id
ip_configuration_name = "primary"
backend_address_pool_id = azurerm_lb_backend_address_pool.pool.id
}
output "public_ip_address" {
value = azurerm_public_ip.lb.ip_address
}
# pip install azure-monitor-querymetrics azure-identity
# Reads the load balancer's health probe results per server, and checks whether outbound SNAT ports are running out.
import datetime as dt
from azure.identity import DefaultAzureCredential
from azure.monitor.querymetrics import MetricAggregationType, MetricsClient
# Metrics are read from a regional endpoint, so use the region of the load balancer.
metrics = MetricsClient("https://centralindia.metrics.monitor.azure.com", DefaultAzureCredential())
NAMESPACE = "Microsoft.Network/loadBalancers"
def backend_health(lb_resource_id, hours=1):
"""Average health probe status per backend address over the last hours: 100 means every probe was answered and 0 means none were.
The load balancer stops sending new connections to a server whose probes fail, so anything below 100 deserves a look."""
result = metrics.query_resources(
resource_ids=[lb_resource_id], metric_namespace=NAMESPACE, metric_names=["DipAvailability"],
timespan=dt.timedelta(hours=hours), granularity=dt.timedelta(minutes=5),
aggregations=[MetricAggregationType.AVERAGE], filter="BackendIPAddress eq '*'")[0]
health = {}
for metric in result.metrics:
for series in metric.timeseries:
values = [point.average for point in series.data if point.average is not None]
if values:
backend = next(iter(series.metadata_values.values()), "unknown")
health[backend] = sum(values) / len(values)
return health
def snat_pressure(lb_resource_id, hours=1):
"""Highest share of the allocated SNAT ports that was in use. Above about 0.8, outbound connections start to fail, so add
a NAT gateway or more outbound addresses."""
result = metrics.query_resources(
resource_ids=[lb_resource_id], metric_namespace=NAMESPACE, metric_names=["UsedSnatPorts", "AllocatedSnatPorts"],
timespan=dt.timedelta(hours=hours), granularity=dt.timedelta(minutes=5),
aggregations=[MetricAggregationType.MAXIMUM])[0]
peak = {}
for metric in result.metrics:
values = [point.maximum for series in metric.timeseries for point in series.data if point.maximum is not None]
peak[metric.name] = max(values) if values else 0
return peak["UsedSnatPorts"] / peak["AllocatedSnatPorts"] if peak.get("AllocatedSnatPorts") else 0.0
if __name__ == "__main__":
lb_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-lb-demo/providers/Microsoft.Network/loadBalancers/lb-web"
for backend, percent in sorted(backend_health(lb_id).items()):
print("%s: %.0f%% of probes answered" % (backend, percent))
print("SNAT ports in use: %.0f%%" % (snat_pressure(lb_id) * 100))
// dotnet add package Azure.ResourceManager.Network
// dotnet add package Azure.Identity
// Audits every load balancer in the subscription: the retired Basic SKU, rules that rely on default outbound SNAT,
// TCP-only probes, and rules without TCP reset.
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Network;
using Azure.ResourceManager.Network.Models;
using Azure.ResourceManager.Resources;
var arm = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await arm.GetDefaultSubscriptionAsync();
int problems = 0;
await foreach (LoadBalancerResource lb in subscription.GetLoadBalancersAsync())
{
LoadBalancerData data = lb.Data;
string name = data.Name;
if (data.Sku?.Name == LoadBalancerSkuName.Basic)
{
Console.WriteLine($"{name}: Basic SKU, which Microsoft retired on 30 September 2025, so upgrade to Standard");
problems++;
}
foreach (ProbeData probe in data.Probes)
{
if (probe.Protocol == ProbeProtocol.Tcp)
{
Console.WriteLine($"{name}/{probe.Name}: TCP probe only proves the port is open, so use an HTTP probe for web servers");
problems++;
}
}
bool hasOutboundRules = data.OutboundRules.Count > 0;
foreach (LoadBalancingRuleData rule in data.LoadBalancingRules)
{
if (rule.DisableOutboundSnat != true && !hasOutboundRules)
{
Console.WriteLine($"{name}/{rule.Name}: outbound SNAT is left on with no outbound rule, which can run out of ports (use a NAT gateway)");
problems++;
}
if (rule.EnableTcpReset != true)
{
Console.WriteLine($"{name}/{rule.Name}: TCP reset is off, so clients learn about idle timeouts late");
problems++;
}
}
}
Console.WriteLine(problems == 0 ? "No problems found." : $"{problems} problem(s) found.");
return problems == 0 ? 0 : 1;
Best videos to explore
Videos picked for this service. Each one is labelled with its source, opens on YouTube if you prefer, and loads only when you press play.
Interview questions
BasicWhat is Azure Load Balancer?
It’s Azure’s layer 4 load balancer. It receives TCP and UDP traffic on a front end address and spreads connections across healthy servers in a backend pool. It can face the internet with a public address or work inside a network with a private one, and it doesn’t look at HTTP content.
BasicWhat is the difference between Azure Load Balancer and Application Gateway?
Azure Load Balancer works at layer 4, so it balances connections quickly without understanding the content. Application Gateway works at layer 7 and understands HTTP: it routes by host and path, terminates TLS, rewrites headers and can run a web application firewall. Many designs use both, with Application Gateway for web traffic and Load Balancer for other tiers.
BasicWhat do health probes do?
Each probe tests a backend server regularly, using TCP, HTTP or HTTPS. A server that fails its probes stops receiving new connections until it passes again. The probes come from the address 168.63.129.16, so network rules must allow them.
IntermediateWhy does a new Standard load balancer seem not to work?
A Standard load balancer is closed to inbound traffic until a network security group allows it, unlike the retired Basic SKU. Check that a rule allows the frontend port to the servers, that the servers are in the backend pool, that the probe passes, and that the operating system firewall isn’t blocking the port.
IntermediateWhat is SNAT port exhaustion, and how do you avoid it?
Servers behind the load balancer reach the internet through source NAT, and each outbound connection to the same destination needs its own port. When many connections use all the ports, new ones fail. A NAT gateway or outbound rules with more addresses supply more ports, connection pooling reduces the need, and the SNAT metrics show how close you are to the limit.
IntermediateHow does the load balancer choose a backend, and when do you change that?
By default it hashes the source and destination address, the ports and the protocol, so one connection always goes to one server and different connections spread out. Client IP persistence sends the same client to the same server, which helps stateful applications but can unbalance load. It balances connections, not load, so long-lived connections can skew the result.
AdvancedHow would you design a zone-redundant internal tier with fast failover?
Create a Standard internal load balancer with a zone-redundant frontend and place backends in all three zones. Use an HTTP probe on a health path that is cheap and independent of slow dependencies, set the threshold and interval for failover in seconds, and turn on TCP reset. Test by stopping servers and a zone’s worth of servers, and check that clients reconnect cleanly.
AdvancedHow do you design outbound connectivity for servers behind a load balancer?
Don’t depend on default outbound access, since new virtual networks are moving to private subnets without it. Attach a NAT gateway to the subnet for the most ports and fixed addresses, or define outbound rules on the load balancer with enough frontend addresses, and disable outbound SNAT on the load balancing rules that you don’t want to use it. Alert on SNAT usage and keep connections pooled.
AdvancedWhen would you use the Gateway SKU and the global tier?
Use the Gateway SKU to insert third-party virtual appliances, such as firewalls, into a traffic path without changing the application, because it preserves the original addresses and chains with Standard frontends. Use the global tier when TCP or UDP services run in several regions and you want one anycast address with failover between regional load balancers.
AdvancedHow would you migrate from the retired Basic SKU to Standard?
Inventory Basic load balancers and Basic public IPs, then use Microsoft’s migration tooling or recreate them as Standard. Standard needs Standard public IPs and a network security group that allows traffic, so plan those rules first, and decide the outbound method before the cut-over. Test in a copy of the environment, schedule a window, and keep the old load balancer until traffic has moved.
Similar or alternative services on other clouds
| Capability | AWS | Azure | Google Cloud |
|---|---|---|---|
| Service | Elastic Load Balancing | Azure Load Balancer and Azure Application Gateway | Cloud Load Balancing |
| HTTP(S), layer 7 | Application Load Balancer | Azure Application Gateway (a separate service) | Application Load Balancers |
| TCP and UDP, layer 4 | Network Load Balancer | Azure Load Balancer (Standard) | Network Load Balancers, proxy and passthrough |
| Network appliances | Gateway Load Balancer | Gateway Load Balancer SKU | Internal passthrough load balancer as a next hop |
| Scope | Regional load balancers, global with Route 53 or Global Accelerator | Regional, with a cross-region tier | Global with one anycast address, or regional |
| Health checks | Per target group | Health probes | Health checks on backend services |
| Certificates | ACM on the listener | Application Gateway certificates, Key Vault | Google-managed or your own |
| Web firewall | AWS WAF on the Application Load Balancer | WAF on Application Gateway | Cloud Armor |
| How you are billed | Hours plus capacity units, plus IPv4 addresses | Rules and data processed | Forwarding rule hours plus data processed |
Typical backends are Azure Virtual Machines and scale sets, and Azure Kubernetes Service creates load balancers for services of type LoadBalancer. For global web traffic in front of it, see Azure Front Door. Metrics and alerts live in Azure Monitor.
Did you find this article helpful?
Your answer helps us improve this page for the next reader.
Sources and further reading
CloudBrum wrote this page in its own words, using the provider’s public documentation listed below as the reference. Features, limits, names and prices change, so confirm anything that matters on the provider’s own pages before you decide.
- What is Azure Load Balancer?Microsoft
- Azure Load Balancer SKUsMicrosoft
- Azure Load Balancer componentsMicrosoft
- Azure Load Balancer health probesMicrosoft
- Load Balancer TCP reset and idle timeoutMicrosoft
- Outbound connections in AzureMicrosoft
- Azure Load Balancer distribution modesMicrosoft
- Load balancing options in AzureMicrosoft
- Azure Load Balancer pricingMicrosoft
- Terraform azurerm: azurerm_lbHashiCorp
