What Is an AG Listener?
An Availability Group listener is a virtual network name that clients use to connect to the databases of an Availability Group. It does not belong to any particular server. It always points to whichever replica is currently the primary.
Technically, a listener is made of three parts:
- A DNS name (for example
SalesLsnr). In a domain it is backed by a computer object in Active Directory, created by the cluster. - One or more IP addresses, one per subnet the AG spans. These are virtual addresses that are online on the node hosting the primary replica.
- A TCP port (ideally 1433).
All of this lives in the Windows Server Failover Cluster (WSFC) as resources inside the AG's cluster role: a Network Name resource and one IP Address resource per subnet. The AG resource depends on them, so they always come online together, on the same node. On Linux, Pacemaker plays the same role with a virtual IP resource.
-- Create a listener for an AG that spans two subnets
ALTER AVAILABILITY GROUP [AG_Sales]
ADD LISTENER N'SalesLsnr' (
WITH IP (
(N'10.10.1.50', N'255.255.255.0'), -- subnet of datacenter A
(N'10.20.1.50', N'255.255.255.0') -- subnet of datacenter B
),
PORT = 1433
);
Listener name is not the AG name
The AG itself also has a name (AG_Sales above), and the two are easy to mix up, especially in environments where they happen to be identical by convention. They are different things: the AG name is just the name of the cluster role and is not registered in DNS. Only the listener is a network name.
To see the real listener names and their state:
SELECT ag.name AS AvailabilityGroup,
l.dns_name AS Listener,
l.port,
ip.ip_address,
ip.state_desc AS IpState -- ONLINE only on the primary's subnet
FROM sys.availability_groups AS ag
JOIN sys.availability_group_listeners AS l
ON l.group_id = ag.group_id
JOIN sys.availability_group_listener_ip_addresses AS ip
ON ip.listener_id = l.listener_id;
Or with dbatools against any replica: Get-DbaAgListener -SqlInstance SQLNODE1.
Why Use the AG Listener?
1. One connection string for every failover
Without a listener, the application connects to SQLNODE1. After a failover, the primary is SQLNODE2, and the application keeps connecting to a server where the database is now a read-only secondary (or not reachable at all). Someone has to change connection strings, configuration files or DNS aliases, under pressure, in the middle of an incident.
With a listener, the connection string says SalesLsnr and never changes. Failover becomes a cluster event, not an application change. This is the main reason a listener exists.
2. Read-only routing
The listener can also send read-only workloads to a readable secondary. A client that connects with ApplicationIntent=ReadOnly to the listener, with an availability database as its initial database, is redirected to a secondary according to the routing list of the current primary. Reporting and other read workloads move off the primary without a second connection string to maintain. Details and pitfalls are in AG Readable Secondaries for Reporting Offload.
3. Multi-subnet and multi-site setups
When an AG spans two datacenters with different subnets, a single IP address cannot follow the primary. The listener holds one IP per subnet and only brings the right one online, so the application still sees one name. Combined with the correct client setting (below), this is what makes cross-site failover workable for applications.
4. Better than a DNS alias
A hand-maintained DNS CNAME to the current primary can do part of this job, but someone (or something) has to update it on every failover, and caching delays the switch. See DNS Aliases for SQL Server for those problems. The listener is updated by the cluster as part of the failover itself.
How the Listener Works During Failover
Here is the sequence when the AG fails over from SQLNODE1 to SQLNODE2, whether planned (manual failover) or automatic after a failure:
- The AG role goes offline on the old primary. The cluster takes the AG resource offline on
SQLNODE1(if that node is still alive). Its dependent resources, the listener's network name and IP addresses, go offline too. All open connections through the listener are dropped at this point, and any open transactions on them are rolled back. - The secondary becomes primary.
SQLNODE2takes over the primary role and runs recovery on the availability databases: committed transactions are rolled forward, uncommitted ones rolled back. The databases come online read-write. - The listener comes online on the new primary's node. The cluster brings the IP address resource online on
SQLNODE2.- Same subnet: the same IP address simply moves to the new node, which announces it on the network. DNS does not change at all.
- Different subnet: the IP of datacenter A stays offline and the IP of datacenter B comes online. What clients see now depends on DNS registration (next section).
- Clients reconnect. The application reconnects to the same listener name and lands on
SQLNODE2. Nothing in the application changed, but it does have to reconnect: the listener does not keep sessions alive across a failover.
Multi-subnet failover: RegisterAllProvidersIP, TTL and MultiSubnetFailover
With one IP per subnet, two cluster settings on the listener's network name decide what DNS returns:
| Setting | What DNS contains | What happens on failover |
|---|---|---|
RegisterAllProvidersIP = 1(default when the listener is created via T-SQL or SSMS) |
All listener IPs, online or not | DNS never changes. A client that tries all IPs at once connects to whichever one is online, within seconds. |
RegisterAllProvidersIP = 0 |
Only the currently online IP | The cluster updates the DNS record. Clients keep using the cached old IP until the record's TTL (HostRecordTTL, default 1200 seconds = 20 minutes) runs out. |
The client side of this is the connection string keyword MultiSubnetFailover=True. It tells the driver to try all IP addresses returned for the name in parallel and use the first one that answers. Without it, the driver tries the addresses one after another and may spend most of the connection timeout waiting on the offline IP in the other datacenter, so connections fail or are slow even when nothing is broken.
Server=tcp:SalesLsnr,1433;Database=SalesDb;Integrated Security=SSPI;MultiSubnetFailover=True;
-- Read-only workload, routed to a readable secondary:
Server=tcp:SalesLsnr,1433;Database=SalesDb;Integrated Security=SSPI;MultiSubnetFailover=True;ApplicationIntent=ReadOnly;
Microsoft recommends MultiSubnetFailover=True for every connection to a listener, even on a single subnet, because it also speeds up reconnection after a failover. Current drivers (Microsoft.Data.SqlClient, ODBC Driver 17/18, recent JDBC) support it. For old clients or applications that cannot set the keyword, the usual compromise is RegisterAllProvidersIP = 0 with a shorter HostRecordTTL (often 300 seconds):
# On a cluster node, as administrator
Get-ClusterResource -Name 'AG_Sales_SalesLsnr' |
Get-ClusterParameter -Name RegisterAllProvidersIP, HostRecordTTL
Get-ClusterResource -Name 'AG_Sales_SalesLsnr' |
Set-ClusterParameter -Multiple @{ RegisterAllProvidersIP = 0; HostRecordTTL = 300 }
# Takes effect only after the network name resource is restarted:
# that takes the listener offline briefly, so plan it like a failover.
What does NOT move with the listener
The listener moves connections to the new primary. It does not move anything that lives outside the availability databases:
- Logins. A SQL login that exists only on the old primary, or exists with a different SID or password, fails on the new one. See Syncing SQL Logins Across an AlwaysOn Availability Group.
- SQL Agent jobs, linked servers, credentials, server-level permissions and configuration.
- Read-only routing lists are per replica: the list of the new primary applies after failover. Every replica that can become primary needs its own list.
Listener Best Practices
- Use port 1433 if you can. With another port, every client must specify it (
SalesLsnr,50001); the SQL Browser service does not help, because the listener has no instance name. - Connect to the listener name only, never with an instance name appended, and never to the AG name.
- Set
MultiSubnetFailover=Truein every connection string to a listener. - Give the cluster permission to create the listener's computer object in Active Directory (or pre-stage it). Missing permissions for the cluster name object are the most common reason listener creation fails.
- Test a failover before go-live, with the real application, and measure how long reconnects take. A connection that works is not the same as a connection that survives a failover.
- In Azure VMs, a classic listener needs an Azure Load Balancer; the simpler option is a Distributed Network Name (DNN) listener, available from SQL Server 2019 CU8 on Windows Server 2016 and later.
A quick check that a listener resolves and lands on the primary:
Test-NetConnection SalesLsnr -Port 1433
Invoke-DbaQuery -SqlInstance 'SalesLsnr' -Query "SELECT @@SERVERNAME AS ConnectedTo, sys.fn_hadr_is_primary_replica('SalesDb') AS IsPrimary"
The Bottom Line
The AG listener is a virtual network name with one IP per subnet and a port, owned by the cluster and always online on the node that hosts the primary replica. Applications connect to it instead of a server name, so a failover needs no configuration change: the cluster moves the listener together with the primary role, and clients only have to reconnect. Use the listener name (not the AG name), port 1433, MultiSubnetFailover=True and proper retry logic, and keep logins and jobs in sync across replicas, because those do not travel with the listener.
For the bigger picture, see Failover Clustering vs. AlwaysOn and Quorum and Witness: Why Failover Fails and How to Fix It.