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 that goes beyond 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.