The Setup
Target: 2-node AlwaysOn AG, Azure — Central US
Link: Distributed Availability Group over ExpressRoute
Database size: Multi-terabyte
This is a textbook Distributed AG topology: two independent WSFC clusters — one on-prem, one in Azure — chained together by a DAG link. See Distributed Availability Groups: Your DBA Tool for Migrations and Multi-Site Deployments for the architecture basics. What's worth breaking apart here is that "is DAG recommended for on-prem to Azure?" actually has two different answers depending on why you're building it.
Topology at a Glance
Use Case 1: Migration
DAG is exactly the right tool here, ExpressRoute or not. ExpressRoute mainly makes the delta-catchup phase faster and more predictable — higher, steadier throughput than a site-to-site VPN over the public internet — which shortens the cutover window.
- Seed manually, not automatically. Automatic seeding over WAN is painfully slow at multi-TB scale, even on ExpressRoute. Use backup/restore, backup-to-URL against Azure Blob, or Azure Data Box for very large databases, then let the DAG catch up the delta.
- The DAG is a bridge, not the end state. Once Azure is caught up and validated, most teams cut over and decommission the on-prem AG rather than running the DAG indefinitely.
- Test the promotion before it matters. Verify the secondary AG is fully caught up, then promote it on a rehearsal run — not for the first time during the real cutover.
For the full T-SQL and step-by-step cutover sequence, see Zero-Downtime SQL Server Migration with Distributed Availability Groups: A Step-by-Step Runbook.
Use Case 2: Permanent DR
Since source and target here are two independent WSFC clusters — on-prem, and a separate cluster in Azure — DAG is actually the standard, supported pattern for this too. You can't sanely stretch a single WSFC across an on-prem datacenter and an Azure region, so DAG isn't a workaround for permanent DR, it's the correct architecture.
With ExpressRoute in place:
- It protects your RPO indirectly. A private, low-jitter circuit keeps the forwarder replica's log-send queue from ballooning under peak write load. That's the main lever ExpressRoute gives you.
- It does not change the commit mode. The inter-AG link in a Distributed AG is always asynchronous, by design, regardless of link quality. Size your RPO expectations around async lag, not around ExpressRoute's speed.
- Failover is a two-step process. Forward-failover the on-prem AG's primary role internally if needed, then failover the DAG itself. For a permanent DR posture that needs to be a tested, documented runbook — not just a topology diagram. Plan failback the same way.
- Budget for always-on standby cost. Two Azure VMs sized for the workload, running continuously, plus the ExpressRoute circuit itself. Worth comparing against your actual RTO/RPO requirements before committing to that spend.
📄 Download the DR Failover & Drill Runbook Template
The permanent-DR counterpart to the migration CutOver Runbook: a fill-in-the-blanks checklist for the two-step failover (internal on-prem failover, then the DAG failover to Azure), the app cutover, a full failback runbook back to on-prem, an abort procedure for a drill gone sideways, a recurring drill log, and an RPO/RTO worksheet. All server names, AG names, and circuit names are placeholders from a sample environment, safe to adapt for your own topology.
⬇ Download distributed-ag-dr-failover-drill-runbook.pdfMigration vs. Permanent DR, Side by Side
| Aspect | DAG for Migration | DAG for Permanent DR |
|---|---|---|
| Lifespan | Temporary bridge, decommissioned after cutover | Indefinite, part of standing architecture |
| ExpressRoute's role | Shortens delta-catchup, shrinks cutover window | Keeps forwarder queue healthy over the long run |
| Failover rehearsal | Once, right before the real cutover | Recurring, on a schedule, including failback |
| Azure replica cost | Short-lived, during migration window | Continuous, sized for real production load |
| Old primary after cutover | Torn down or kept briefly as rollback safety net | Stays as the permanent primary; Azure is the DR leg |
New-sqmDistributedAvailabilityGroup creates the DAG link, Add-sqmDatabaseToDistributedAg adds databases to it, Test-sqmDistributedAgReadiness checks the forwarder queue and sync state before you promote anything, Get-sqmDistributedAgHealth gives you an ongoing health report for the ExpressRoute-fed forwarder queue, and Invoke-sqmDistributedFailover runs the promotion — useful both for a one-time cutover and for regular DR failover drills.
Full command reference: sqmSQLTool commands.
Summary
Yes to Distributed AG on-prem to Azure over ExpressRoute, for both use cases — but they're not the same project:
- For a migration, DAG replaces the old backup/restore cutover with a near-zero-downtime promotion. ExpressRoute just makes the catchup faster.
- For permanent DR, DAG is the correct pattern because you're bridging two independent clusters. ExpressRoute protects your RPO by keeping the async queue small — it does not, and cannot, make the link synchronous.
Seed manually at TB scale, rehearse the two-step failover before you need it, and size your RPO around "always async" rather than around circuit speed.
For the underlying architecture and failover mechanics, see Distributed Availability Groups: Your DBA Tool for Migrations and Multi-Site Deployments.