Databases & HA

Azure SQL Database vs Managed Instance vs SQL Server VM: How to Choose

Compare Azure SQL Database, Azure SQL Managed Instance and SQL Server on Azure VMs on compatibility, high availability, limits, cost model and management, then pick one with a repeatable assessment.

14 min read
On this page

Choose Azure SQL Database for new or cloud-native applications that work within a single database and can live without instance-level features, Azure SQL Managed Instance when you are moving an existing SQL Server instance that depends on SQL Server Agent, cross-database queries, CLR, Service Broker or Database Mail, and SQL Server on Azure VMs when you need operating system access, a specific engine version, unsupported features, or more storage than the managed services allow. The deciding factors are almost always instance-level dependencies first, storage size second, and only then cost and high availability. This guide gives you the comparison and a step-by-step assessment that turns it into a decision.

Who this is for and what you will have at the end

This is for database administrators, architects and platform engineers who own one or more SQL Server workloads and need to place them in Azure, either as part of a data center exit or for a new application. It assumes you know SQL Server and have read access to the source instances.

At the end you will have:

  • A clear picture of what each Azure SQL option supports and what it takes away.
  • A set of T-SQL inventory queries that expose the instance-level dependencies that usually decide the target.
  • A sizing, high availability and cost checklist for each candidate.
  • A short proof-of-concept plan to confirm the choice before you migrate production.

If the database move is part of a wider program, the enterprise Azure cloud migration playbook covers the landing zone, wave planning and cutover governance around it.

The three options at a glance

All three products run the SQL Server database engine. The difference is how much of the stack Azure manages and how much of the engine surface you get.

AreaAzure SQL DatabaseAzure SQL Managed InstanceSQL Server on Azure VMs
Service modelPaaS, database scoped (single database or elastic pool on a logical server)PaaS, instance scopedIaaS, full VM and OS
Engine versionLatest stable engine, compatibility via database compatibility levelLatest stable engine, with an update policy aligned to SQL Server 2022, SQL Server 2025 or Always-up-to-dateAny supported version (2016, 2017, 2019, 2022, 2025) and edition
Feature compatibilityMost database-level featuresAlmost all instance-level and database-level featuresFull parity with the installed version
Maximum storageUp to 4 TB (General Purpose, Business Critical); up to 128 TB (Hyperscale)Up to 16 TB classic General Purpose, 32 TB Next-gen General Purpose, up to 16 TB Business Critical depending on hardware and regionInstances with up to 256 TB
High availabilityBuilt in, zone redundancy available on vCore tiers and DTU PremiumBuilt in, zone redundancy availableYou design it (Always On availability groups or failover cluster instances)
BackupsAutomated only, 1 to 35 days PITR, up to 10 years LTRAutomated plus user-initiated COPY_ONLY backups to Blob StorageYour choice: automated backup through the IaaS Agent extension, Azure Backup, or your own jobs
NetworkPublic endpoint with firewall rules, or private endpoint via Private LinkPrivate IP in a dedicated subnet of your virtual networkPrivate IP in your virtual network
ScalingOnline change of compute and storage; serverless autoscaleOnline change of vCores and storageVM resize causes downtime

Two numbers in that table often settle the decision on their own. If a single database is larger than 4 TB and you want Azure SQL Database, Hyperscale is the only tier that fits. If an instance needs more than the Managed Instance storage ceiling for your hardware and region, a VM is the remaining option.

Compatibility: what you lose when you leave a full instance

Azure SQL Database removes the instance. That is the source of most migration blockers, because applications built against on-premises SQL Server often rely on things that live outside a single database. Managed Instance keeps the instance, so it removes most, but not all, of those blockers.

FeatureAzure SQL DatabaseAzure SQL Managed Instance
SQL Server AgentNo (use elastic jobs)Yes, with documented differences
Cross-database (three-part name) queriesNo (use elastic query)Yes
Cross-database transactionsNoYes, within the instance
Linked serversNoYes, to SQL Server and SQL Database, without distributed transactions
CLRNoYes, without file system access in CREATE ASSEMBLY
Database MailNoYes
Service BrokerNoYes, with documented differences
Distributed transactions (MS DTC)No (elastic transactions)Yes
BACKUP commandNo, system-initiated backups onlyCOPY_ONLY backups to Azure Blob Storage
RESTORE from .bakNoYes, FROM URL only
Windows authenticationNoYes, for Microsoft Entra principals
FILESTREAMNoNo
Machine Learning ServicesNoYes, with the SQL Server 2022 update policy
SSRSNoNo (can host the catalog databases for a report server on a VM)
Active geo-replicationYes, all tiersNo, use failover groups

SQL Server on Azure VMs supports everything in the installed edition, so anything marked "No" for both PaaS services is a reason to look at a VM. FILESTREAM and running SSRS alongside the engine are the common examples.

Managed Instance has one setting that deserves attention early: the update policy. With the SQL Server 2022 or SQL Server 2025 policy, the internal database format stays aligned with that SQL Server release, so you can restore a database back to SQL Server of that version and use the Managed Instance link for bidirectional failover. With the Always-up-to-date policy you get new engine features as soon as they ship, but you lose the ability to restore to SQL Server, and the change is one-way. Instances in a failover group must have matching update policies.

High availability and disaster recovery

Both PaaS services include high availability with no configuration, using one of two architectures depending on the service tier.

  • General Purpose (and DTU Basic and Standard in SQL Database) separates stateless compute from database files in Azure storage. If the node fails, Azure Service Fabric starts the engine on another node and reattaches the files. It is resilient, but the new node starts with a cold cache.
  • Business Critical (and DTU Premium) runs a cluster with a primary and up to three secondary replicas on local SSD, using technology similar to Always On availability groups. Failover is to a fully synchronized replica, and one secondary is readable at no extra charge through Read Scale-Out.
  • Hyperscale (SQL Database only) separates compute, page servers and log service, and lets you choose 0 to 4 high availability replicas.

Zone redundancy spreads replicas or storage across availability zones in the region. In SQL Database it is available on the General Purpose, Business Critical and Hyperscale vCore tiers and on DTU Premium, but not on DTU Basic or Standard. For Hyperscale it can only be set when the database is created. In Managed Instance it is available on General Purpose and Business Critical, with zone redundancy for Next-gen General Purpose in preview.

For disaster recovery across regions, SQL Database offers active geo-replication and failover groups on all tiers; Managed Instance offers failover groups. Microsoft documents a guaranteed RPO of 5 seconds and RTO of 30 seconds for Business Critical databases with active geo-replication.

On a VM the picture is different. The Azure SLA for two VMs in an availability set or across availability zones covers the virtual machines, not the SQL Server process running on them. To make the databases highly available you configure Always On availability groups or a failover cluster instance yourself. That gives you full control, including the exact replica layout and the recovery model, but you own the design, testing and patching of the cluster.

Cost and licensing model

The services are billed differently, which makes direct comparison harder than it looks.

  • Azure SQL Database has a DTU model and a vCore model. In the vCore model you pay for compute, reserved storage and backup storage, with a serverless compute tier billed per second. Business Critical allocates three extra replicas, which Microsoft states makes it approximately 2.7 times the cost of General Purpose. Hyperscale has no SQL license fee, so Azure Hybrid Benefit isn't available for new Hyperscale databases.
  • Azure SQL Managed Instance charges for vCores, reserved storage and backup storage. You pay for the maximum storage you reserve, in multiples of 32 GB. Next-gen General Purpose also charges for IOPS above the built-in 3 IOPS per GB of reserved storage. Instance pools let several small instances share resources.
  • SQL Server on Azure VMs costs the VM size, the disks, and the SQL Server license. With marketplace images you pay per-minute licensing for SQL Server and the operating system, or you bring your own license with Azure Hybrid Benefit.

Azure Hybrid Benefit and Azure Reservations apply across the family (with the Hyperscale exception above). The cost you can't see on the price list is administration: with a VM you spend time on patching, backup verification and cluster maintenance that the PaaS services include.

Step 1: Inventory instance-level dependencies

Run these queries on each source instance. Anything they return is a feature that Azure SQL Database won't support, and a few of them also matter for Managed Instance.

-- SQL Server Agent jobs (none in SQL Database; script and recreate on MI)
SELECT name, enabled FROM msdb.dbo.sysjobs ORDER BY name;
 
-- Linked servers
SELECT name, product, provider, data_source
FROM sys.servers
WHERE is_linked = 1;
 
-- User-defined CLR assemblies (run in each user database)
SELECT name, permission_set_desc
FROM sys.assemblies
WHERE is_user_defined = 1;
 
-- Cross-database and cross-server references (run in each user database)
SELECT OBJECT_NAME(referencing_id) AS referencing_object,
       referenced_server_name,
       referenced_database_name,
       referenced_entity_name
FROM sys.sql_expression_dependencies
WHERE referenced_database_name IS NOT NULL;
 
-- Service Broker and FILESTREAM usage
SELECT name, is_broker_enabled FROM sys.databases;
SELECT DB_NAME(database_id) AS database_name, name
FROM sys.master_files
WHERE type_desc = 'FILESTREAM';

Read the results with these rules:

  • Any Agent jobs, linked servers, CLR assemblies, cross-database references or Service Broker usage rule out Azure SQL Database unless you are willing to change the application.
  • FILESTREAM rules out both PaaS services.
  • Dependencies on the operating system, such as scripts that call the file system, third-party agents installed on the host, or SSRS on the same server, point to a VM.

For a fuller automated assessment, Microsoft's current migration guidance uses the migration assessment in SQL Server enabled by Azure Arc, and lists T-SQL differences for Managed Instance in the documentation linked in the references.

Step 2: Check size and throughput limits

Compare the largest database and total instance size against the limits:

  • SQL Database General Purpose and Business Critical support 1 GB to 4 TB per database. Hyperscale supports 10 GB to 128 TB.
  • Managed Instance General Purpose supports up to 100 user databases per instance (500 on Next-gen General Purpose), and in classic General Purpose each data file is limited to 8 TB, so databases larger than that need at least two data files.
  • Managed Instance General Purpose log write throughput is limited to 4.5 MiB/s per vCore with a per-instance cap, while Business Critical allows 16 MiB/s per vCore up to its cap. Write-heavy workloads should be measured against these numbers.
  • Storage I/O latency is documented as roughly 5 to 10 ms on classic General Purpose, 3 to 5 ms on Next-gen General Purpose and 1 to 2 ms on Business Critical.

Step 3: Decide your availability target

Write down the RPO and RTO each workload needs and whether it must survive an availability zone outage. Then map it:

  • Zone-level resilience with no cluster to run: a zone-redundant PaaS tier.
  • Read offload: Business Critical (one readable replica included) or Hyperscale named replicas.
  • Cross-region DR: failover groups on either PaaS service, or availability group replicas in a second region on VMs.
  • Custom replica topology, distributed availability groups or a recovery model other than full: a VM.

Step 4: Decide who manages what

Be honest about operational capacity. With SQL Database and Managed Instance you still manage logins, indexes, query tuning, auditing and security, but not the OS, engine patching or backups. On a VM you choose when to patch and what else runs on the host. If you choose a VM, register it with the SQL Server IaaS Agent extension. The extension is free and unlocks portal management, licensing changes, automated backup, automated patching through Azure Update Manager, Azure Key Vault integration and best practices assessment. Marketplace images register automatically.

# Check the IaaS Agent extension and its backup and patching settings
$sqlext = Get-AzVMSqlServerExtension -VMName "sql01" -ResourceGroupName "rg-data"
$sqlext.AutoPatchingSettings
$sqlext.AutoBackupSettings
 
# List SQL Server VMs that use Azure Hybrid Benefit
Get-AzSqlVM | Where-Object { $_.LicenseType -eq 'AHUB' }

Step 5: Run a proof of concept

Before committing, move one representative database to the candidate target and run its real workload. For Managed Instance, a native restore is the quickest test:

-- On the managed instance: credential for the container holding the .bak
CREATE CREDENTIAL [https://contosomigration.blob.core.windows.net/backups]
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
     SECRET = '<sas-token>';
 
RESTORE DATABASE [Sales]
FROM URL = 'https://contosomigration.blob.core.windows.net/backups/Sales.bak';

For production migrations to Managed Instance, the documented online options are the Managed Instance link, Log Replay Service and Azure Database Migration Service. If the database uses TDE, migrate the certificate before restoring. Logins, Agent jobs and other objects in master and msdb don't move with the database; script and recreate them.

Verification

Once the target is running, confirm that you got what you planned for:

-- Engine version and edition on any target
SELECT @@VERSION;
 
-- Managed Instance only: CU = SQL Server 2022 or 2025 policy, Continuous = Always-up-to-date
SELECT SERVERPROPERTY('ProductUpdateType');

Then test failover behavior with your application's retry logic in place. For SQL Database use Invoke-AzSqlDatabaseFailover (or Invoke-AzSqlElasticPoolFailover for a pool), and for Managed Instance use Invoke-AzSqlInstanceFailover. Only one failover call is allowed every 15 minutes per database, pool or instance, so plan your test runs accordingly.

Troubleshooting common decision blockers

The application uses three-part names across databases. Azure SQL Database doesn't support cross-database queries. Either consolidate the objects into one database, rewrite the queries to use elastic query, or move to Managed Instance, which supports cross-database queries and transactions within the instance.

Restore to SQL Server is a compliance requirement. Keep Managed Instance on the SQL Server 2022 or SQL Server 2025 update policy that matches your on-premises version. Changing to Always-up-to-date permanently upgrades the database format, and backups from such an instance can only be restored to another Always-up-to-date instance.

A Hyperscale database needs zone redundancy after creation. The setting can't be changed on an existing Hyperscale database. Use a database copy, point-in-time restore or a geo-replica to create a zone-redundant copy.

Managed Instance deployment fails or can't be reached. Managed Instance needs a dedicated subnet delegated to Microsoft.Sql/managedInstances, with a network security group and a route table associated and at least 32 IP addresses. Azure Policy deny assignments, resource locks, a NAT gateway or IPv6 prefixes on the subnet can also make deployments fail. Check the network requirements in the connectivity architecture documentation before provisioning.

The VM SLA doesn't cover a SQL Server outage. The VM SLA covers the virtual machines only. Add an availability group or failover cluster instance if the databases themselves must stay available.

Decision checklist

  • Inventory queries run on every source instance and results recorded.
  • FILESTREAM, OS dependencies or unsupported features found: SQL Server on Azure VMs.
  • Agent jobs, cross-database queries, CLR, Service Broker or linked servers found, and no OS dependency: Azure SQL Managed Instance.
  • Single-database application with none of the above: Azure SQL Database (Hyperscale if larger than 4 TB).
  • Largest database and total instance size checked against the tier limits for your region and hardware.
  • RPO, RTO and zone requirements mapped to a tier, and failover tested with application retry logic.
  • Update policy chosen deliberately for Managed Instance.
  • VMs registered with the SQL Server IaaS Agent extension, with backup and patching configured.
  • Proof of concept completed with a real workload before the production migration.

References

Questions people ask

What is the main difference between Azure SQL Database and Azure SQL Managed Instance?

Azure SQL Database is a managed database scoped to a single database or an elastic pool behind a logical server, so instance-level features such as SQL Server Agent, cross-database queries, CLR, Database Mail and Service Broker are not available. Azure SQL Managed Instance is a managed SQL Server instance in your virtual network with near-complete engine compatibility, so it supports those instance-scoped features while Azure still handles patching, backups and high availability.

When should I run SQL Server on an Azure VM instead of a PaaS option?

Choose a VM when you need operating system access, a specific SQL Server version or edition, features the PaaS services don't offer (for example FILESTREAM or SSRS on the same host), or more storage than Managed Instance allows. You take on patching, backups and high availability design yourself, although the SQL Server IaaS Agent extension can automate backups and patching.

Does Azure SQL Managed Instance let me take native backups?

Yes, but only user-initiated COPY_ONLY backups to Azure Blob Storage; the regular automated backups are managed by the service. You can restore those backups to SQL Server 2022 or SQL Server 2025 only if the instance uses the matching update policy, not the Always-up-to-date policy.

What is the maximum database size in each Azure SQL option?

Azure SQL Database Hyperscale supports up to 128 TB, while General Purpose and Business Critical single databases support up to 4 TB. Managed Instance reserved storage goes up to 16 TB on classic General Purpose, 32 TB on Next-gen General Purpose and up to 16 TB on Business Critical depending on hardware and region. SQL Server on Azure VMs supports instances with up to 256 TB of storage.

Azure SQL DatabaseAzure SQL Managed InstanceSQL Server on Azure VMsAzure
  1. Azure SQL Database Backups: Point-in-Time Restore, LTR and Geo-Restore

    Set PITR retention and backup redundancy, add a long-term retention policy, and run point-in-time, deleted-database, LTR and geo-restores for Azure SQL Database and Managed Instance.

    Databases & HA13 min read
  2. Azure SQL Entra Authentication: Entra-Only Mode and Managed Identity

    Replace SQL logins on Azure SQL Database and Managed Instance with Microsoft Entra ID: set the Entra admin, create users for groups and managed identities, then enable Entra-only authentication.

    Databases & HA11 min read
  3. Azure SQL Failover Groups: Configure Geo-Failover for Database and MI

    Create Azure SQL failover groups for SQL Database and Managed Instance, point apps at the listener endpoints, choose a failover policy and run planned and forced failover drills.

    Databases & HA13 min read