From RDS to Aurora

From RDS to Aurora: A Migration Checklist for Mid-Size Teams

Version checks, storage limits (128-256 TiB), endpoint switching, and load tests

The problem

Teams hit scaling ceilings on Amazon RDS: storage growth, replica lag, spiky latency during maintenance. Aurora offers faster failovers, storage auto-scaling, and cheaper read scaling. Migrations hurt when basics are missed: engine/version mismatches, wrong storage assumptions, sloppy DNS cutovers, and unproven throughput. This checklist keeps the outage window boring.


The high-level plan

  1. Decide the target (Aurora MySQL vs Aurora PostgreSQL; Serverless v2 vs provisioned).
  2. Prove compatibility (engine + version parity, features, extensions).
  3. Validate limits (cluster storage up to 256 TiB on current Aurora; per-table/instance constraints; connections). (Amazon Web Services, Inc.)
  4. Build a green environment (cluster + replicas + parameters + endpoints). (AWS Documentation)
  5. Replicate data (physical clone, DMS, logical replication, or Blue/Green). (AWS Documentation)
  6. Load test and rehearse (sysbench/pgbench + production-like data).
  7. Cut over with DNS hygiene (CNAME, low TTL, rollback plan).
  8. Observe and optimize (perf schema/pg_stat*, Aurora metrics).

Step-by-step checklist

1) Choose the right Aurora flavor

  • Aurora MySQL v3 (MySQL 8.0 compatible). On RDS MySQL 5.7, do the app & SQL uplift before migrating. (AWS Documentation)
  • Aurora PostgreSQL: confirm needed extensions (PostGIS, pgcrypto, etc.) exist in the target Aurora engine version.
  • Storage model: Aurora auto-scales storage at the cluster level - current max 256 TiB (was 128 TiB). RDS engine instances typically cap at 64 TiB. Plan growth accordingly. (Amazon Web Services, Inc.)
  • Serverless v2 can work for bursty, cost-sensitive loads; steady heavy traffic prefers provisioned. Check any regional/feature constraints (e.g., Limitless Aurora Postgres requirements). (AWS Documentation)

2) Version & feature parity (blockers surface here)

Create a small matrix and refuse to proceed until it is green:

AreaSource (RDS)Target (Aurora)Check
Engine + majore.g., MySQL 8.0.28Aurora MySQL v3.* (8.0-compatible)Verify behavior diffs (temp tables, keywords). (AWS Documentation)
Extensions/Featurese.g., pgcrypto, logical decodesAurora Postgres version supports them?Confirm availability/replacements
Parameter diffsinnodb_flush_log_at_trx_commit, sql_mode / work_memAurora paramsCreate a parameter group twin
AuthenticationIAM auth / SSLSameEnforce TLS, rotate certs

Tip: Read the "v2 vs v3" diffs for Aurora MySQL; there are subtle behavior changes. (Amazon Docs)

3) Limits & quotas

  • Cluster storage: Aurora MySQL & Postgres now support up to 256 TiB per cluster (pay for what you use). (Amazon Web Services, Inc.)
  • Per-table size: Aurora MySQL max table size 64 TiB (practically limited by engine/DDL). Track large tables explicitly. (AWS Documentation)
  • RDS baseline: most RDS engines max 64 TiB storage per instance - useful for sizing deltas and growth runway math. (AWS Documentation)

4) Build the green (target) environment properly

  • Create writer and reader endpoints; add custom endpoints to route hot read pools by workload. Remember: custom endpoints aren't saved in snapshots; recreate after restores. (AWS Documentation)
  • Match parameter groups, option groups, subnets, security groups, and maintenance windows.

5) Data movement options (pick one and practice)

  • RDS → Aurora Read Replica (for MySQL): attach Aurora replica to RDS, then promote when lag ≈ 0. Near-zero downtime if app is replica-aware. (AWS Documentation)
  • RDS Blue/Green Deployments: create mirrored green env; switch over in minutes. Understand that "switch over" ≠ "promote a read replica." Follow the doc workflow to avoid invalid states. (AWS Documentation)
  • AWS DMS: full load + CDC into Aurora (engine-agnostic; good for heterogeneous features or heavy transforms). (AWS Documentation)

6) Endpoint switching & DNS hygiene (cutover)

  • Use CNAMEs (e.g., db.prod.myco → Aurora writer endpoint).
  • Lower TTL (e.g., set to 30-60s at least 24h before).
  • Drain writes: set app to read-only for final sync if you are not using blue/green or replication-based approaches.
  • Rollback: keep old writer on standby with replication paused; cut back via DNS if needed.
  • If you opt for Blue/Green, do the official switch over step - do not manually "Promote" the green instance or you will break the deployment state. (AWS Documentation)

7) Load testing (prove it before you flip)

The pre-cutover test must answer: Can Aurora sustain peak P95 latency and steady-state throughput with headroom?

  • Workload tools:
    • MySQL → sysbench oltp_read_write with realistic table cardinalities and secondary indexes.
    • PostgreSQL → pgbench custom scripts mirroring your transaction mix.
  • Scale reads: point read pools to the reader or custom endpoints to validate connection poolers. (AWS Documentation)
  • Observe: CloudWatch metrics (CommitLatency, Deadlocks, AuroraReplicaLag, DatabaseConnections, AuroraVolumeBytesLeftTotal). That last one exposes remaining storage - watch it during the rehearsal. (AWS Documentation)
  • Concurrency: validate pool sizes and max connections (Aurora may allow different ceilings than RDS instance families).

8) Performance hardening (pre- and post-cutover)

  • MySQL: confirm redo/flush settings, innodb_buffer_pool_size (if not Serverless), and long-query killer in app tier.
  • PostgreSQL: cost settings, work_mem, autovacuum aggressiveness on hot partitions; verify extension versions.
  • SQL fixes: resolve full table scans with missing compound indexes; test plan stability under Aurora's optimizer variants.
  • Maintenance: pick a patch window out of your peak; Aurora failovers are faster than RDS but still visible in tail latency - test it.

Practical mini-runbook

Quick storage sanity

# RDS (source) storage ceiling reminder (most engines):
# 64 TiB per instance (use to sanity-check explosive growth)
# Ref: AWS docs

(AWS Documentation)

-- Big tables inventory (MySQL)
SELECT table_schema, table_name,
       ROUND((data_length+index_length)/POWER(1024,3),2) AS size_gb
FROM information_schema.tables
ORDER BY size_gb DESC
LIMIT 20;

Blue/Green or replica approach rehearsal

# If using DNS cutover, prep a friendly CNAME and shrink TTL
# (do this at least a day before)
# Route 53 -> Hosted zone -> A/AAAA or CNAME: db.prod.myco
# Set TTL = 60
# App connection string should point to your friendly CNAME, not raw endpoint
DB_HOST=db.prod.myco

Reader routing proof

# Aurora exposes a reader endpoint for read-only traffic
# Validate the pooler routes to it and your reports/BI keep working.
# Ref: Aurora endpoints doc

(AWS Documentation)

Sysbench smoke (MySQL example)

sysbench oltp_read_write --mysql-host=db-green.myco \
  --mysql-user=bench --mysql-password=*** \
  --tables=24 --table-size=2000000 --threads=128 --time=600 prepare

sysbench oltp_read_write --mysql-host=db-green.myco \
  --mysql-user=bench --mysql-password=*** \
  --tables=24 --table-size=2000000 --threads=128 --time=600 run

Post-cutover validation

  • Error budget unchanged, P95/99 latencies within SLO.
  • Replica lag ≈ 0, readers healthy, connections balanced.
  • No rapid storage consumption; AuroraVolumeBytesLeftTotal stable. (AWS Documentation)

Best practices & common pitfalls

Best practices

  • Rehearse the switch at least twice with production-sized data.
  • Abstract the endpoint behind your own DNS, which simplifies the next move.
  • Right-size readers and use custom endpoints to isolate heavy analytical/reporting workloads from web/API reads. (AWS Documentation)
  • Use Blue/Green when supported to minimize downtime and risk. (AWS Documentation)
  • Track version-specific behavior (e.g., Aurora MySQL v3 nuances vs MySQL 8.0 community). (AWS Documentation)

Pitfalls

  • Assuming 128 TiB is still the max. As of mid-2025, Aurora MySQL & Postgres support 256 TiB - update your capacity models. (Amazon Web Services, Inc.)
  • Forgetting custom endpoints after restores (snapshots don't keep them). Recreate them. (AWS Documentation)
  • Manual "Promote" during Blue/Green - that breaks the deployment state. Use the official switch action. (AWS Documentation)
  • Copying RDS params verbatim - Aurora has different defaults and behaviors; test and tune.

Conclusion

Aurora can cut failover times, scale reads cheaply, and extend storage runway to 256 TiB per cluster - but only with a disciplined migration. Lock down version parity, validate limits, build proper endpoints, load test with production-like data, and execute a scripted cutover. That turns the migration into a controlled routine instead of a midnight firefight.

Summary

  • Pick the right Aurora edition and confirm version/feature parity.
  • Validate limits (cluster storage up to 256 TiB; table size nuances). (Amazon Web Services, Inc.)
  • Build green env with writer/reader/custom endpoints; rehearse load. (AWS Documentation)
  • Prefer Blue/Green or replica-based switchovers; perform DNS cutover cleanly. (AWS Documentation)

Sources

Leave a Comment