---
title: "How to Migrate SQL Server to Azure SQL Database"
description: "Learn how to migrate SQL Server to Azure SQL Database using Azure DMS and SqlPackage, covering assessment with Azure Arc, schema migration, data movement, and post-migration validation."
canonical: "https://adamtheautomator.com/migrate-sql-server-azure-sql-database/"
---

# How to Migrate SQL Server to Azure SQL Database

> Learn how to migrate SQL Server to Azure SQL Database using Azure DMS and SqlPackage, covering assessment with Azure Arc, schema migration, data movement, and post-migration validation.

Source: https://adamtheautomator.com/migrate-sql-server-azure-sql-database/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![How to Migrate SQL Server to Azure SQL Database](https://adamtheautomator.com/wp-content/uploads/2026/02/featured_image-20.webp)

# How to Migrate SQL Server to Azure SQL Database

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)25 February 20266 min. read

Categories: [Cloud](/category/cloud/)

Tags:[Azure](/tag/azure/)[Azure PowerShell](/tag/azure-powershell/)[Azure SQL Database](/tag/azure-sql-database/)[Databases](/tag/databases/)

Table of Contents

*   [Prerequisites](#prerequisites)
*   [Phase 1: Assess Your Database](#phase-1-assess-your-database)
*   [Phase 2: Migrate the Schema](#phase-2-migrate-the-schema)
*   [Phase 3: Migrate the Data](#phase-3-migrate-the-data)
*   [Phase 4: Validate and Optimize](#phase-4-validate-and-optimize)
*   [Choosing the Right Service Tier](#choosing-the-right-service-tier)
*   [What to Watch After Cutover](#what-to-watch-after-cutover)

You’ve been running the same SQL Server instance on aging hardware for years. The patching cycles are relentless, the licensing costs keep climbing, and your DBA just handed you a migration project with a deadline. Moving to [Azure SQL Database](https://azure.microsoft.com/en-us/products/azure-sql/database/)—Microsoft’s fully managed Platform-as-a-Service (PaaS) database offering—gets you out of the infrastructure business. No more manual backups, no patching OS layers, no worrying about disk capacity at 2 a.m.

This guide walks you through the three phases of an actual migration: assessment, data movement, and post-migration validation. You’ll use the tools Microsoft currently recommends, including [Azure Database Migration Service (DMS)](https://learn.microsoft.com/en-us/azure/dms/dms-overview) and [SqlPackage](https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage).

## Prerequisites

Before you touch anything, confirm your environment meets these requirements:

*   SQL Server 2008 or later on your source instance (DMS supports this range)
    
*   An Azure subscription with Contributor or Owner access
    
*   A target Azure SQL Database already provisioned
    
*   Network connectivity from your on-premises server to Azure (VPN or [ExpressRoute](https://learn.microsoft.com/en-us/azure/expressroute/expressroute-introduction), or firewall rules opened for public endpoints)
    
*   The [Az.DataMigration PowerShell module](https://learn.microsoft.com/en-us/azure/dms/migration-dms-powershell-cli) installed: `Install-Module -Name Az.DataMigration`
    
*   [SqlPackage](https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage) installed on a machine with source database access
    

One thing to set expectations on upfront: DMS migrations to Azure SQL Database are **offline only**. Your application goes down when the migration starts, and comes back up when it ends. If that’s a problem, [Azure SQL Managed Instance](https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/sql-managed-instance-paas-overview) supports online migration—but that’s a different target and a different post.

Before starting, provision your target Azure SQL Database. You’ll need a logical SQL server in Azure and a database with enough DTU (Database Transaction Unit) or vCore capacity for your workload. If you’re unsure about sizing, the assessment phase (below) will give you right-sized SKU recommendations—run the assessment before you provision, not after.

* * *

**_Pro Tip: If you’re still using the Azure SQL Migration extension for Azure Data Studio, stop. It has reached end-of-life. The Azure portal and PowerShell are the supported paths going forward._**

* * *

## Phase 1: Assess Your Database

You can’t migrate what you don’t understand. Skipping the assessment phase is how people discover incompatibilities at 11 p.m. during the actual cutover.

If your SQL Server instances are enrolled in [Azure Arc](https://learn.microsoft.com/en-us/sql/sql-server/azure-arc/overview), you get [continuous migration assessment](https://learn.microsoft.com/en-us/sql/sql-server/azure-arc/migration-assessment) for free—no separate tool required. The [Migration Dashboard](https://learn.microsoft.com/en-us/sql/sql-server/azure-arc/migration-inventory) in the Azure portal shows readiness status, compatibility issues, and SKU recommendations calculated from actual workload data. It runs on a weekly schedule automatically.

For instances not on Azure Arc, enroll them now:

```
# Install the Azure Connected Machine agent on your SQL Server host
# Then register it with Arc using the azcmagent binary
azcmagent connect `
  --resource-group "rg-migration" `
  --location "eastus" `
  --subscription-id "<your-subscription-id>"
```

The [assessment readiness report](https://learn.microsoft.com/en-us/sql/sql-server/azure-arc/migration-assessment) classifies each database as:

| Status | Meaning |
| --- | --- |
| Ready | No blockers—can migrate as-is |
| Ready with conditions | Minor issues to resolve before migration |
| Not ready | Compatibility blockers exist; may need target change |

“Not ready” for Azure SQL Database often means you’re using features like SQL Server Agent jobs or cross-database queries. Those are available in Managed Instance—worth noting if you hit that wall.

* * *

**_Key Insight: A “Not ready” result is not a dead end. Most blockers stem from feature gaps that Azure SQL Managed Instance handles. Check both targets before ruling out the PaaS path entirely._**

* * *

## Phase 2: Migrate the Schema

Here’s where most guides quietly skip a critical step: DMS migrates **data only**. Your schema has to exist in the target database before DMS runs, or the migration fails.

Export your schema from the source using SqlPackage’s `Extract` action, which produces a [DACPAC file](https://learn.microsoft.com/en-us/sql/relational-databases/data-tier-applications/data-tier-applications)—a portable snapshot of your database schema:

```
sqlpackage /Action:Extract \
  /SourceServerName:"your-sql-server" \
  /SourceDatabaseName:"YourDatabase" \
  /SourceUser:"sa" \
  /SourcePassword:"YourPassword" \
  /TargetFile:"YourDatabase.dacpac"
```

Then publish the schema to your Azure SQL Database target:

```
sqlpackage /Action:Publish \
  /SourceFile:"YourDatabase.dacpac" \
  /TargetServerName:"yourserver.database.windows.net" \
  /TargetDatabaseName:"YourDatabase" \
  /TargetUser:"sqladmin" \
  /TargetPassword:"YourPassword"
```

* * *

**_Warning: SqlPackage’s Publish action is destructive by default—it drops and recreates objects to match the DACPAC. Run it against a fresh database, not a production target with existing data._**

* * *

Verify the schema landed correctly before moving on:

```
-- Run against your Azure SQL Database target
SELECT TABLE_NAME, TABLE_TYPE
FROM INFORMATION_SCHEMA.TABLES
ORDER BY TABLE_NAME;
```

If your table count matches the source, you’re ready for data movement.

## Phase 3: Migrate the Data

With schema in place, you can run the DMS migration. DMS uses a [Self-Hosted Integration Runtime (SHIR)](https://learn.microsoft.com/en-us/azure/data-factory/create-self-hosted-integration-runtime)—a secure agent installed on your network—to read data from your source and push it to Azure without requiring direct inbound connections.

Start by creating a DMS instance if you don’t have one:

```powershell
New-AzDataMigrationSqlService `
  -ResourceGroupName "rg-migration" `
  -Name "dms-prod" `
  -Location "eastus"
```

Register your SHIR with the DMS service. You’ll [download and install the SHIR](https://learn.microsoft.com/en-us/azure/dms/migration-using-azure-data-studio#install-self-hosted-integration-runtime) from the Azure portal under your DMS resource, then install it on an on-premises machine with line-of-sight to your source SQL Server, and register it with an authentication key generated during setup. The SHIR machine needs outbound HTTPS access (port 443) to Azure—it doesn’t require inbound firewall rules, which is why it works even when your SQL Server sits behind a corporate firewall.

Verify the SHIR is connected and healthy before starting the migration:

```
# Check SHIR status
Get-AzDataMigrationSqlService `
  -ResourceGroupName "rg-migration" `
  -Name "dms-prod" | Select-Object -ExpandProperty IntegrationRuntimeState
```

A status of `Online` means you’re good to proceed. `Limited` or `Offline` means the SHIR can’t reach Azure—check the machine’s outbound network rules before burning time on a migration attempt.

Here’s a quick reference for SHIR states and what they tell you:

| SHIR State | Meaning | Next Step |
| --- | --- | --- |
| Online | Connected and healthy | Proceed with migration |
| Limited | Partial connectivity | Check specific node logs |
| Offline | Cannot reach Azure | Check outbound port 443 rules |

Then kick off the migration:

```powershell
New-AzDataMigrationToSqlDb `
  -ResourceGroupName "rg-migration" `
  -SqlDbInstanceName "yourserver" `
  -TargetDbName "YourDatabase" `
  -MigrationService "/subscriptions/<sub-id>/resourceGroups/rg-migration/providers/Microsoft.DataMigration/sqlMigrationServices/dms-prod" `
  -Scope "/subscriptions/<sub-id>/resourceGroups/rg-migration/providers/Microsoft.Sql/servers/yourserver/databases/YourDatabase" `
  -SourceSqlConnectionAuthentication "SqlAuthentication" `
  -SourceSqlConnectionDataSource "your-sql-server" `
  -SourceSqlConnectionUserName "sa" `
  -SourceSqlConnectionPassword "YourPassword" `
  -SourceDatabaseName "YourDatabase" `
  -TargetSqlConnectionAuthentication "SqlAuthentication" `
  -TargetSqlConnectionDataSource "yourserver.database.windows.net" `
  -TargetSqlConnectionUserName "sqladmin" `
  -TargetSqlConnectionPassword "YourPassword"
```

Monitor migration status:

```powershell
Get-AzDataMigrationToSqlDb `
  -ResourceGroupName "rg-migration" `
  -SqlDbInstanceName "yourserver" `
  -TargetDbName "YourDatabase"
```

The `State` field moves from `InProgress` to `Succeeded` when data movement completes. The full sample scripts for this pattern are available in the [Azure-Samples/data-migration-sql repository](https://github.com/Azure-Samples/data-migration-sql).

* * *

**_Key Insight: For smaller databases where downtime isn’t a concern, you can skip DMS entirely and use a BACPAC file instead. SqlPackage’s Export action bundles schema and data into one file—simpler, but not suitable for large or transactionally active databases due to consistency risks._**

* * *

## Phase 4: Validate and Optimize

The migration completes, you flip your connection strings, and you’re done. Sort of.

Before you declare victory, run row count checks to confirm data completeness:

```
-- Run this on both source and target, compare results
SELECT
  t.name AS TableName,
  p.rows AS RowCount
FROM sys.tables t
JOIN sys.partitions p ON t.object_id = p.object_id
WHERE p.index_id IN (0, 1)
ORDER BY t.name;
```

Once you’ve confirmed row counts match, let your workload run for a few days before you optimize. [Query Performance Insight](https://learn.microsoft.com/en-us/azure/azure-sql/database/query-performance-insight-use) surfaces the top resource-consuming and long-running queries across your workload—check it after you have real traffic to analyze.

Azure SQL Database’s [automatic tuning](https://learn.microsoft.com/en-us/azure/azure-sql/database/monitor-tune-overview) can create and drop indexes based on workload patterns without manual intervention. Enable it, then verify what it’s doing rather than letting it run blind:

```
-- Check auto-tuning recommendations in your target database
SELECT name, reason, score, details
FROM sys.dm_db_tuning_recommendations
WHERE JSON_VALUE(state, '$.currentValue') = 'Active'
ORDER BY score DESC;
```

A common post-migration surprise: queries that ran fine on-premises slow down on Azure SQL Database because the service tier’s DTU or vCore count doesn’t match your actual workload. The [Performance Guidance documentation](https://learn.microsoft.com/en-us/azure/azure-sql/database/performance-guidance) covers how to interpret monitoring data and scale appropriately. Scaling up is one CLI command:

```bash
az sql db update \
  --resource-group rg-migration \
  --server yourserver \
  --name YourDatabase \
  --service-objective S4
```

### Choosing the Right Service Tier

If you provisioned your target database based on a guess rather than the Arc assessment recommendations, you may need to resize after observing real-world traffic. Azure SQL Database offers two purchasing models:

| Model | Best For | Scaling |
| --- | --- | --- |
| DTU (Basic, Standard, Premium) | Predictable workloads, simpler management | Fixed resource bundles |
| vCore (General Purpose, Business Critical, Hyperscale) | Variable workloads, need CPU/memory separation | Independent CPU and memory control |

For most migrations from on-premises SQL Server, the vCore model gives you more predictable cost mapping—your on-premises server has a known core count, and vCore pricing translates directly.

## What to Watch After Cutover

Migrating from SQL Server to Azure SQL Database follows a predictable sequence: assess compatibility with Azure Arc, migrate schema with SqlPackage, move data with DMS, and validate before cutting over production traffic. The pieces that cause problems are almost always the ones people skip—either the assessment phase (which surfaces compatibility blockers before you’re committed) or the schema migration step (which DMS won’t handle for you).

If you hit a “not ready” assessment result, don’t immediately assume the migration is stuck. Many blockers come down to feature gaps that Azure SQL Managed Instance handles—checking both targets side by side before ruling out the PaaS path entirely is worth the time.

The tools Microsoft recommends change periodically—the Azure SQL Migration extension for Azure Data Studio has reached end-of-life, and the Data Migration Assistant (DMA) has been deprecated. Staying with the [Azure portal DMS workflow](https://learn.microsoft.com/en-us/data-migration/sql-server/database/database-migration-service) and the [Az.DataMigration PowerShell module](https://learn.microsoft.com/en-us/azure/dms/migration-dms-powershell-cli) keeps you on the supported path.

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fmigrate-sql-server-azure-sql-database%2F&text=How%20to%20Migrate%20SQL%20Server%20to%20Azure%20SQL%20Database)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fmigrate-sql-server-azure-sql-database%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fmigrate-sql-server-azure-sql-database%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/publisher/3075d9c85b2b811696d7c3fb28215d5b/2632cbcaed949b31f4a9b4c4ea73d850076a5034cf55e309a5815dd451ab0388.webp)

### [Stop Scaling Azure SQL: Find Real Performance Issues](/azure-sql-performance-tuning/)

Use Azure's built-in diagnostics to find real performance bottlenecks in your Azure SQL Database instead of scaling up immediately.

![](https://adamtheautomator.com/wp-content/uploads/2026/04/featured_image-15.webp)

### [Fix Azure Cost Reporting with a FinOps Tagging Strategy](/fix-azure-cost-reporting-finops-tagging-strategy-3/)

Build an Azure resource tagging taxonomy, enforce it with Azure Policy, and automate remediation of untagged resources to enable accurate FinOps cost allocation and chargebacks.

![](https://adamtheautomator.com/wp-content/uploads/2026/04/featured_image-10.webp)

### [Automate SOC 2 Compliance with PowerShell and Azure](/automate-soc-2-compliance-powershell-azure/)

Learn how to use Azure Policy, the EPAC framework, and PowerShell to automate SOC 2 compliance evidence collection, enforce controls across subscriptions, and build a continuous audit trail.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
