Chapter 16 · Always On Availability Groups, Failover Cluster Instances, and HA Design

Readable Secondaries, Read-Only Routing, Backups, Lag, Seeding, and Application Intent

Use readable secondaries, listener read-only routing, backup preferences and automatic seeding with explicit lag, capacity and client-routing semantics.

Advanced175–220 minutesread-scale & routing labSQL Server 2025 CU7 · 17.0.4065.4Compatibility 170 · Developer/Express simulationSSMS 22.8.2 · Last reviewed August 2026

Learning outcomes

Once ServiceHub has an advanced AG, teams often try to “use the secondary for reporting and backups.” That can be useful, but it creates a new correctness contract. A readable secondary exposes data only after redo. A backup preference is a policy hint to jobs, not enforcement. Read-only routing happens only for qualifying client connections through the listener. Automatic seeding consumes the same network and storage resources the workload depends on.

01

Explain readable-secondary consistency in terms of hardened log, redo progress and queue evidence.

02

Configure the mental model for listener-based read-only routing and ApplicationIntent=ReadOnly.

03

Distinguish AG backup preference from actual job execution and use sys.fn_hadr_backup_is_preferred_replica correctly.

04

Assess automatic seeding as a capacity event rather than a zero-cost convenience.

05

Reject stale-read and Basic-AG assumptions that do not match SQL Server 2025 edition capabilities.

1. A readable secondary is not a synchronous cache

Secondary reads see the state that redo has applied. Even a synchronous-commit secondary can have a redo queue because commit acknowledgment is tied to hardening, not read visibility after redo. Long-running queries can also interact with row versioning on readable secondaries. Report consumers must decide whether seconds/minutes of lag are acceptable and whether “read your own write” semantics are required.

sql · turn queues into a freshness-oriented diagnostic view
SELECT DB_NAME(database_id) AS database_name,       synchronization_state_desc,       synchronization_health_desc,       log_send_queue_size AS log_send_queue_kb,       redo_queue_size AS redo_queue_kb,       last_hardened_time,last_redone_time,       DATEDIFF(second,last_redone_time,SYSUTCDATETIME()) AS seconds_since_last_redoFROM sys.dm_hadr_database_replica_statesWHERE is_local=1;GO

A queue size is a point-in-time observation, not an SLA by itself. Combine it with log generation rate, redo rate, latency, workload and timestamps. A large remote queue can be network-latency or throughput pressure; a redo queue can be secondary CPU/I/O/redo pressure.

2. Read-only routing is a four-part contract

For automatic read-only routing, the AG needs a listener; the secondary must allow read connections; replicas need read-only routing URLs/lists; and the client must connect to the listener with a database in the AG plus ApplicationIntent=ReadOnly. Without those pieces, SQL Server cannot infer that an ordinary client connection should be redirected.

text · application connection strings — supported concept, replace names/authentication
# Microsoft.Data.SqlClient style examples# Primary/read-write intent:Server=tcp:ServiceHubListener;Database=ServiceHubLab;Encrypt=True;TrustServerCertificate=False;ApplicationIntent=ReadWrite;# Qualifying read-only routing request:Server=tcp:ServiceHubListener;Database=ServiceHubLab;Encrypt=True;TrustServerCertificate=False;ApplicationIntent=ReadOnly;MultiSubnetFailover=True;
sql · inspect listener and routing metadata on a real AG
SELECT ag.name AS ag_name,agl.dns_name,agl.port,agl.is_conformantFROM sys.availability_groups AS agJOIN sys.availability_group_listeners AS agl ON agl.group_id=ag.group_id;GOSELECT ar.replica_server_name,ar.secondary_role_allow_connections_desc,       ar.read_only_routing_url,ar.backup_priorityFROM sys.availability_replicas AS ar;GO
Wrong approach: point reporting directly at SQL-B and call it HA.

Direct instance addressing can be useful for a pinned workload, but it bypasses listener-based role/routing abstraction. If SQL-B changes role or is unavailable, the application must own that failover logic. Decide explicitly whether you want pinned routing or AG routing.

Check your understanding

  1. Why can a readable synchronous secondary return older data than the primary?
  2. What client setting is required for read-only routing?
  3. Does AUTOMATED_BACKUP_PREFERENCE block a backup on a nonpreferred replica?
  4. Why should seeding be scheduled/observed as a capacity event?
  5. Can a SQL Server 2025 Standard Basic AG serve reports or backups from its secondary?
Review the answers

1. Redo can lag behind hardening, so the secondary read surface may not yet include the newest hardened log.

2. ApplicationIntent=ReadOnly on a qualifying connection to the AG listener/database, with routing configured server-side.

3. No. The job must evaluate the preference, commonly with sys.fn_hadr_backup_is_preferred_replica().

4. It transfers and writes the database, consuming network, storage and processing resources.

5. No. Basic AG secondary read access and secondary backups are not supported.

3. Backup preference is advisory, not enforcement

AUTOMATED_BACKUP_PREFERENCE records where you prefer backups to run. SQL Server does not stop a backup command that violates that preference. Your Agent or external scheduler must query the preference and decide whether to proceed. Microsoft provides sys.fn_hadr_backup_is_preferred_replica() for this reason.

sql · gate an AG-aware backup job on the preferred replica
DECLARE @db sysname=N'ServiceHubLab';SELECT @db AS database_name,       sys.fn_hadr_backup_is_preferred_replica(@db) AS is_preferred_here;IF sys.fn_hadr_backup_is_preferred_replica(@db) <> 1BEGIN    PRINT 'Not the preferred backup replica; exit this job successfully.';    RETURN;END;PRINT 'Preferred here; continue with the approved backup procedure.';GO

In a real fleet, deploy the same job logic to candidate replicas and make media paths/credentials available where needed. Remember the Standard Basic AG limitation: it does not allow backups on its secondary, so this offload pattern is for supported advanced-AG topologies.

4. Secondary workload isolation is an HA concern

Read scale can compete directly with recovery readiness. Reporting queries consume CPU, memory grants, buffer-pool pages and storage bandwidth on the secondary. Backups consume I/O and CPU, especially with compression/encryption. Redo needs CPU and storage to apply incoming log. If reporting saturates the replica and redo falls behind, the very secondary intended as a failover target can become less ready for failover. Resource governance and workload scheduling therefore belong in the HA design, not only the performance chapter.

Use Query Store and normal performance evidence on readable replicas where supported, but interpret it with role awareness. A plan that is fine on the primary may encounter different cache warmth, hardware, statistics timing or concurrent workload on a secondary. Read-only routing lists can distribute connections, yet SQL Server does not provide a general-purpose load balancer with application session affinity guarantees. Test the actual reporting workload and connection pattern.

sql · record role-aware workload evidence before blaming AG transport
SELECT @@SERVERNAME AS connected_instance,       DB_NAME() AS database_name,       DATABASEPROPERTYEX(DB_NAME(),'Updateability') AS updateability,       sys.fn_hadr_is_primary_replica(DB_NAME()) AS is_primary_replica;GOSELECT wait_type,waiting_tasks_count,wait_time_msFROM sys.dm_os_wait_statsWHERE wait_type IN(N'REDO_THREAD_PENDING_WORK',N'DB_MIRROR_SEND',N'HADR_SYNC_COMMIT',N'WRITELOG', N'PAGEIOLATCH_SH',N'RESOURCE_SEMAPHORE')ORDER BY wait_time_ms DESC;GO

Some diagnostics and waits are cumulative since reset/startup, so capture deltas over a known interval. A high cumulative wait after months of uptime is not proof of a current incident. Likewise, do not solve secondary pressure by disabling protection settings or moving all backups to the primary without measuring the new failure and capacity tradeoffs.

5. Automatic seeding is an initialization workload

Automatic seeding avoids manually restoring a full/log chain to initialize a secondary, but SQL Server must still transfer the database and create it on the target. Large databases can saturate network links, consume I/O and extend backup/redo queues. Check target free space, throughput, seeding state and error logs before assuming a slow join is “stuck.”

sql · optional seeding evidence on a real AG
SELECT local_database_name,role_desc,internal_state_desc,       transfer_rate_bytes_per_second,transferred_size_bytes,       database_size_bytes,start_time,completion_time,failure_state_descFROM sys.dm_hadr_automatic_seedingORDER BY start_time DESC;GO

6. Production judgment

Readable secondaries are capacity and consistency tools, not zero-lag caches. Define maximum tolerated reporting staleness and verify it from redo evidence. Configure clients with current drivers, TLS validation, listener names and appropriate connection timeout/retry behavior. In multisubnet deployments, use driver guidance for MultiSubnetFailover. Protect secondary resources so reporting, backups and seeding do not starve redo.

The final lesson turns these mechanics into drills: quorum loss, service/node/network failure, planned failover, automatic failover and forced failover—with client reconnect evidence and explicit data-loss authorization.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.