Cloud Databases

Migrate On-Premises SQL Server to Amazon RDS: Native Backup/Restore vs AWS DMS

A step-by-step guide to migrating an on-premises Microsoft SQL Server database to Amazon RDS for SQL Server — covering native backup/restore via S3 with the rds_restore_database stored procedure, AWS DMS full-load + CDC for near-zero downtime, option group and IAM setup, cutover, and post-migration hardening.

JusDB Team
June 2, 2026
15 min read
0 views

Moving an on-premises Microsoft SQL Server database to Amazon RDS for SQL Server is one of the most common — and most quietly risky — migrations a DBA runs. RDS is a managed service, which means you give up sysadmin, lose direct filesystem access, and can no longer run a plain RESTORE DATABASE FROM DISK. The good news: AWS gives you two well-trodden paths, and picking the right one for your downtime budget is most of the battle. This guide walks both — the native backup/restore via Amazon S3 route for simple lift-and-shift, and AWS DMS for near-zero-downtime cutovers — with the exact stored procedures, IAM, and option-group setup RDS requires.

TL;DR
  • RDS for SQL Server is managed: no sysadmin role, no OS access, and the only supported restore path is through the native backup/restore option backed by an S3 bucket.
  • Option 1 — Native backup/restore (S3): back up on-prem to a .bak file, upload to S3, and restore with the rds_restore_database stored procedure. Simple, but requires downtime for the final backup.
  • Option 2 — AWS DMS: full load plus change data capture (CDC) keeps the target in sync while the source stays live — the path for near-zero-downtime cutovers.
  • RDS needs an option group with SQLSERVER_BACKUP_RESTORE and an IAM role granting access to the S3 bucket before any restore will work.
  • Hard limits: 16 TB max database size; native restore is offline for that database; DMS does not migrate logins, jobs, or SQL Agent — you migrate those separately.
  • Always run a compatibility and feature check first — RDS does not support every on-prem feature (e.g. certain CLR, FILESTREAM, cross-database ownership chaining nuances).

The Migration at a Glance

Every SQL Server-to-RDS migration moves through the same five phases regardless of which data-movement path you pick. Keeping this end-to-end shape in mind stops the common failure of jumping straight to the restore before the landing zone or compatibility checks are done.

SQL Server to Amazon RDS Migration Phases

SQL Server to Amazon RDS migration phases Five phases left to right: Assess, Build landing zone, Migrate data, Cutover, and Optimize, each with an outcome note. 1 ASSESSversionsfeatures16 TB capsizinglogins / jobs 2 BUILDlanding zoneVPC / SGRDS instanceoption groupIAM + S3 3 MIGRATEdataOpt 1: S3 .bakOpt 2: DMS CDC 4 CUTOVERquiescefinal deltaremap loginsrepoint 5 OPTIMIZEMulti-AZbackupsstats / indexesbaseline plan.md infra ready in sync app live production hardened
The five-phase migration path, with the outcome each phase delivers.

Why You Can't Just Restore a .bak the Old Way

On a self-managed SQL Server, migrating a database is a one-liner: copy the .bak to the new server's disk and RESTORE DATABASE. Amazon RDS removes that option on purpose. As a managed service, RDS does not give you the host operating system, does not grant the sysadmin server role, and does not let you place files on the instance's disk. Instead, AWS exposes a controlled native backup and restore feature that moves backup files through Amazon S3 and runs the actual restore on your behalf via a set of msdb stored procedures.

That single architectural fact drives everything else in this guide: you will stage backups in S3, grant RDS an IAM role to read that bucket, enable the feature through an option group, and orchestrate the restore through stored procedures rather than T-SQL RESTORE statements.

Important

RDS for SQL Server caps a single database at 16 TB. If your source is larger, you must split it, archive cold data, or evaluate Amazon EC2 (self-managed SQL Server) instead. Validate this before you plan anything else.

Choosing Your Migration Path

The decision comes down to one question: how much downtime can you tolerate?

FactorNative backup/restore (S3)AWS DMS (full load + CDC)
DowntimeHours — offline during final backup, upload, and restoreMinutes — cutover only, source stays live
ComplexityLow — a handful of stored proceduresHigher — replication instance, endpoints, tasks
FidelityExact byte-for-byte copy of the databaseSchema + data; logins/jobs/Agent handled separately
Best forMaintenance-window cutovers, smaller DBs, one-shot moves24×7 systems, large DBs, minimal-downtime requirements
CDC requirementNoneFull recovery model + transaction log backups on source

Pick Your Path

Choosing a migration path A decision on whether a maintenance window is acceptable, branching to Option 1 native backup/restore via S3, or Option 2 AWS DMS full load plus CDC. Can you take a maintenance window(hours offline) for cutover? YES NO OPTION 1Native backup/restorevia Amazon S3simple, exact copyoffline for the restore OPTION 2AWS DMSfull load + CDCsource stays livecut over in minutes
One question — how much downtime you can tolerate — picks the path.

Prerequisites: What to Validate Before You Touch Anything

Both paths share the same planning checklist. Skipping these is how migrations slip from a weekend to a month.

  • Version & edition compatibility. Confirm your source SQL Server version and edition are supported as an RDS target. Map Enterprise-only features (e.g. certain partitioning, TDE specifics, Resource Governor) against what RDS exposes.
  • Feature support. RDS does not support every on-prem feature. Audit for FILESTREAM, certain CLR assemblies, cross-database ownership chaining, distributed transactions, Service Broker across instances, and linked servers — each may need rework.
  • Sizing. Right-size the RDS instance class (vCPU/RAM) and storage (gp3 vs io2 IOPS) against your current workload, not your current hardware. Over-provisioned on-prem boxes don't translate one-to-one.
  • Network. VPC, subnets, and security groups that allow your migration host (and DMS replication instance, if used) to reach both source and target on TCP 1433.
  • What RDS won't bring over automatically. Server-level logins, SQL Agent jobs, linked servers, server-level triggers, and credentials live in master/msdb — script these out and reapply them on the target.
Warning

Native backup/restore copies the user database only. Server-level objects — logins, jobs, alerts, operators, linked servers — are not included. Orphaned users (database users whose matching server login is missing) are the single most common post-migration failure. Plan to script logins from the source and remap them with ALTER USER ... WITH LOGIN after restore.

Configure the Target: VPC, RDS Instance, Option Group, IAM

Before either migration path, stand up the landing zone. The order matters because the native restore feature depends on the option group and IAM role existing first. Here is how the pieces wire together inside your AWS account:

Landing Zone Architecture (in your AWS account)

RDS landing zone architecture A VPC holds a Multi-AZ RDS for SQL Server across two subnets; the instance assumes an IAM role; an option group uses that role, which has s3:GetObject on an S3 bucket holding the staged backup. VPC (us-east-1) Private subnet AZ-a Private subnet AZ-b Amazon RDS for SQL Server (Multi-AZ)primary -- sync replication -- standby security group: inbound TCP 1433 from app + migration host assumes IAM role Option groupSQLSERVER_BACKUP_RESTORE IAM rolerds-s3-backup-restore+ (optional) KMS grant uses s3:GetObject S3 bucketstaged .bak
How the VPC, RDS instance, option group, IAM role, and S3 bucket wire together.

1. Network and instance

Create (or reuse) a VPC with private subnets across at least two Availability Zones, a DB subnet group, and a security group that allows inbound TCP 1433 from your migration host and application tier. Then launch the RDS for SQL Server instance with the engine version and license model (License Included or BYOL) you validated.

2. Option group with native backup/restore

The native backup/restore feature is delivered through an RDS option group. Create one for your engine version and add the SQLSERVER_BACKUP_RESTORE option, pointing it at the IAM role you'll create next, then attach the option group to the instance.

Create the Option Group

RDS option group setup steps Ordered steps: open RDS Console option groups and create a group, pick the engine, add the SQLSERVER_BACKUP_RESTORE option with an IAM role, then attach the group to the DB instance. 1 RDS Console > Option groups > Create group 2 Engine: sqlserver-se / -ee / -ex / -web 3 Add option: SQLSERVER_BACKUP_RESTORE IAM role: rds-s3-backup-restore-role 4 Attach the option group to the DB instance
Enabling native backup/restore through an RDS option group.

3. S3 bucket and IAM role

Create an S3 bucket in the same Region to stage backup files, then an IAM role that RDS can assume to read from (and write to, for export) that bucket. The trust policy allows the RDS service to assume the role; the permission policy grants object access on the bucket.

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:GetBucketLocation"],
      "Resource": "arn:aws:s3:::my-sqlserver-migration"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload"],
      "Resource": "arn:aws:s3:::my-sqlserver-migration/*"
    }
  ]
}
Tip

If your backups are encrypted with KMS, the IAM role also needs kms:DescribeKey, kms:GenerateDataKey, and kms:Decrypt on the key, and the SQLSERVER_BACKUP_RESTORE option must reference the same KMS key. Skipping the KMS grants is the most common reason a restore task silently fails on encrypted .bak files.

Option 1: Native Backup and Restore via Amazon S3

This is the simplest path and the right default when you can afford a maintenance window. The flow is: back up on-prem → upload to S3 → restore on RDS via stored procedure → verify.

Native Backup/Restore Data Flow

Native backup and restore data flow On-prem SQL Server backs up to a .bak file, which is copied to an S3 bucket via aws s3 cp, then restored into Amazon RDS for SQL Server via rds_restore_database. On-prem SQLServer (source) 1. BACKUP DATABASE .bakfile 2. upload aws s3 cp S3bucket 3. rds_restore_database Amazon RDS forSQL Server
Backup on-prem, upload to S3, restore into RDS via stored procedure.

Step 1 — Back up the source database

Take a full backup on the on-premises instance. Use compression to shrink the upload and CHECKSUM to catch corruption early.

sql
BACKUP DATABASE [SalesDB]
TO DISK = N'D:\backups\SalesDB_full.bak'
WITH COMPRESSION, CHECKSUM, STATS = 5;

Step 2 — Upload the backup to S3

bash
aws s3 cp D:\backups\SalesDB_full.bak \
  s3://my-sqlserver-migration/SalesDB_full.bak \
  --region us-east-1

Step 3 — Restore into RDS with the stored procedure

Connect to the RDS instance as the master user and call rds_restore_database. There is no RESTORE DATABASE here — the procedure queues an asynchronous task that RDS executes.

sql
EXEC msdb.dbo.rds_restore_database
  @restore_db_name   = 'SalesDB',
  @s3_arn_to_restore_from = 'arn:aws:s3:::my-sqlserver-migration/SalesDB_full.bak';

Step 4 — Track the restore task

The call returns a task_id immediately; the restore runs in the background. Poll its status until it reports SUCCESS.

sql
-- All recent tasks:
EXEC msdb.dbo.rds_task_status @db_name = 'SalesDB';

-- Or a specific task:
EXEC msdb.dbo.rds_task_status @task_id = 5;

Watch the lifecycle column move through CREATED → IN_PROGRESS → SUCCESS. The % complete and task_info columns surface progress and any error detail.

Warning

You cannot restore a database that already exists on the RDS instance, and you cannot run two restore tasks for the same database at once. If a restore fails midway, drop the partial target database before retrying. Differential and log restores are supported, but you must restore them in order using @type = 'DIFFERENTIAL' and the WITH NORECOVERY-style chaining the feature provides — plan the chain if you're minimizing downtime with a final log restore at cutover.

Step 5 — Reduce downtime with a differential or log tail

To shrink the window, take the full backup early, restore it to RDS while the source keeps running, then at cutover take a final differential (or log) backup, upload it, and restore just that delta. This turns a multi-hour full-restore window into a short final-delta window.

Option 2: AWS DMS for Near-Zero-Downtime Migration

When the database is large or the system runs 24×7, AWS Database Migration Service (DMS) is the answer. DMS performs an initial full load of existing data and then uses change data capture (CDC) to replicate ongoing changes, keeping the RDS target continuously in sync with the live source until you flip the application over.

AWS DMS Full-Load + CDC

AWS DMS full load plus CDC A DMS replication instance in a VPC reads full load and CDC from the on-prem source endpoint and applies changes to the Amazon RDS target endpoint. On-prem SQLServer (source) source endpoint Amazon RDS forSQL Server target endpoint DMS replicationinstance (in VPC)runs the task full load + CDC reads apply changes
DMS reads full load and CDC from the live source and applies to RDS.

DMS setup at a glance

  1. Prepare the source for CDC. The source database must use the FULL recovery model and have regular transaction log backups running, so DMS can read ongoing changes from the log.
  2. Create a replication instance in the same VPC, sized for your change volume.
  3. Create source and target endpoints (on-prem SQL Server and the RDS instance) and run Test connection on both.
  4. Create a migration task with migration type Migrate existing data and replicate ongoing changes, plus table mappings selecting the schemas to move.
  5. Monitor via CloudWatch and the task's table statistics; watch CDCLatencySource and CDCLatencyTarget approach zero before cutover.
Important

DMS migrates table data and (with the schema-conversion step) structure — but it does not migrate SQL Server logins, SQL Agent jobs, server-level triggers, or linked servers. Treat those as a separate workstream: script them from the source and apply them to the target before cutover.

Tip

DMS is excellent at moving rows, not at performance tuning the pipeline. If your full load is slow or CDC latency creeps up, see our AWS DMS performance tuning guide for parallel-load settings, LOB handling, and batch-apply tuning that routinely cut migration time in half.

Cutover: Switching the Application Over

Cutover is where preparation pays off. A clean cutover follows the same shape regardless of path — and the order is what keeps the downtime window short and the rollback option open:

Cutover Sequence (downtime window)

Cutover sequence and downtime window Five steps left to right: quiesce writes, final delta, reconcile and validate, repoint the app, and keep the source read-only as rollback. Steps 1 through 4 are the application-offline window. source live RDS live cutover window time 1 QUIESCEwrites(read-only) 2 FINAL DELTAdiff/logrestoreor CDC=0 3 RECONCILE+ VALIDATElogins,counts,checksum 4 REPOINTapp connstring to RDSre-enablewrites 5 KEEPsourceread-onlyas rollbackfor N hours application offline
The ordered cutover steps; the application is offline across steps 1-4.
  1. Quiesce writes on the source (stop the application or set the source database read-only).
  2. Apply the final delta — restore the final differential/log backup (Option 1) or wait for DMS CDC latency to hit zero (Option 2).
  3. Reconcile server-level objects — confirm logins, jobs, and linked servers exist on the target; fix orphaned users.
  4. Validate — run row counts, checksums on critical tables, and a smoke test of the application against RDS.
  5. Repoint the application connection string to the RDS endpoint and re-enable writes.
  6. Keep the source available (read-only) for a rollback window before decommissioning.

Fix orphaned users after restore

sql
-- Find users whose login no longer maps:
SELECT dp.name AS orphaned_user
FROM sys.database_principals dp
LEFT JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE dp.type IN ('S','U') AND sp.sid IS NULL AND dp.authentication_type_desc = 'INSTANCE';

-- Remap to an existing login on the target:
ALTER USER [app_user] WITH LOGIN = [app_user];

Post-Migration: Make It Production-Ready

Restoring data is not the finish line. Before you call the migration done:

  • Enable Multi-AZ for high availability if it wasn't created that way — RDS handles the synchronous standby and failover.
  • Configure automated backups and a retention period; set the backup and maintenance windows off-peak.
  • Re-establish maintenance. RDS has no SQL Agent sysadmin, so adapt your index/stats maintenance accordingly — our Ola Hallengren maintenance setup guide covers running the standard maintenance solution on RDS.
  • Update statistics and rebuild indexes after the bulk load so the optimizer has fresh data.
  • Baseline performance with Performance Insights and wait statistics — see the SQL Server wait stats diagnostic playbook to confirm the new instance is sized correctly under real load.
  • Decommission the DMS replication instance, the S3 staging objects, and the on-prem source only after the rollback window closes.

Frequently Asked Questions

Can I restore a .bak file directly to Amazon RDS for SQL Server?

Not with a normal T-SQL RESTORE DATABASE statement — RDS does not grant filesystem or sysadmin access. You upload the .bak to an S3 bucket and restore it using the msdb.dbo.rds_restore_database stored procedure, after enabling the SQLSERVER_BACKUP_RESTORE option and granting RDS an IAM role for the bucket.

What's the largest database I can migrate to RDS for SQL Server?

A single database is limited to 16 TB. Larger databases must be split, have cold data archived, or be hosted on self-managed SQL Server on Amazon EC2 instead.

Should I use native backup/restore or AWS DMS?

Use native backup/restore when you can take a maintenance window and want a simple, exact copy. Use AWS DMS (full load + CDC) when you need near-zero downtime, the database is large, or the system runs 24×7 and cannot go offline for hours.

Does the migration bring over my logins and SQL Agent jobs?

No. Both paths migrate the user database contents but not server-level objects. Script out logins, SQL Agent jobs, alerts, operators, and linked servers from the source and reapply them on the RDS target, then fix any orphaned database users with ALTER USER ... WITH LOGIN.

How do I check the status of an RDS restore?

The rds_restore_database call returns a task_id and runs asynchronously. Poll EXEC msdb.dbo.rds_task_status @db_name = 'YourDB'; and watch the lifecycle column move from CREATED to IN_PROGRESS to SUCCESS.

Key Takeaways
  • Validate version, feature, and 16 TB size compatibility before anything else — RDS does not support every on-prem SQL Server feature.
  • Stand up the option group (SQLSERVER_BACKUP_RESTORE), S3 bucket, and IAM role first — the native restore depends on all three.
  • Choose native backup/restore for window-based cutovers and AWS DMS for near-zero-downtime migrations.
  • Restore with rds_restore_database and track progress with rds_task_status — there is no direct RESTORE DATABASE.
  • Migrate logins, jobs, and linked servers separately, and fix orphaned users at cutover.
  • Finish the job: enable Multi-AZ, restore maintenance, refresh statistics, and baseline performance before decommissioning the source.

Migrating SQL Server to AWS with JusDB

A migration pattern tells you the happy path; production migrations are where the edge cases live — unsupported features that surface at restore time, CDC latency that won't converge, orphaned logins discovered after cutover, and the rollback plan you hope you never need. JusDB's database team runs SQL Server-to-RDS migrations end to end: compatibility assessment, landing-zone setup, native backup/restore and DMS pipelines, cutover orchestration with minimal downtime, and post-migration tuning and 24×7 support across RDS, Aurora, and self-managed SQL Server on EC2.

If you're planning a move off on-premises SQL Server — or want a second set of eyes on a cutover plan — talk to the JusDB team. For the pipeline internals behind Option 2, read the AWS DMS performance tuning guide, and to validate the target instance under load, see the SQL Server wait stats diagnostic playbook.

Share this article

JusDB Team

Official JusDB content team