Aurora serverless — Worked Examples and Scale-to-Zero Rules
Companion to instructions.md and formulas-and-examples.md. The formulas and pricing tables used to produce these numbers live in formulas-and-examples.md.
Worked example — basic sizing
User asks: db.r6g.xlarge, CPU P95 35%, max 72%, 500 GiB storage, should I switch to Aurora serverless? Region: us-east-1.
Agent reply should follow this pattern — present the script output, no derivation shown:
"Loading
references/serverless-advisory-instructions.md— this is the serverless sizing workflow.The command to run this analysis yourself from a machine with Python 3.10+ and boto3 installed:
python3 scripts/acu_calculator.py estimate \ --instance db.r6g.xlarge --cpu-p95 35 --cpu-max 72 --storage 500 --region us-east-1Running that with your parameters produces:
Metric Value min ACU 3.5 max ACU 16.0 typical ACU 6.0 Peak ACU vs 256 ceiling Well under (12.0/256)
Monthly cost Amount Provisioned db.r6g.xlarge compute $379 Aurora serverless at typical ACU compute $526 Aurora serverless total range (min–max, incl. storage) $357–$1,452 Storage (500 GiB × $0.10) $50 Total Provisioned / Total Aurora serverless (typical) $429 / $576 Recommendation: not_recommended. At typical load, Aurora serverless is ~34% more expensive than provisioned ($576 vs $429). Your workload (P95 35%, max 72%) is steady — the burst/idle pattern that makes serverless win isn't present. Stay on db.r6g.xlarge. If you want the savings anyway, consider a 1-year RI on the provisioned instance (~30% off compute), which brings total to ~$315/mo."
Note what this reply does NOT include: no "0.21 × 4 × 4 = 3.36, round up to 3.5" arithmetic; no formula derivation; no "here's how I computed it." Just the script-style output.
(The internal formulas for producing these numbers are in formulas-and-examples.md. Use them to generate the output, but don't copy them into the reply.)
Worked example — migration with connection and working-set constraints
User: db.r7g.2xlarge, 200 peak connections, 12 GiB working set, P95 40%, max 65%, 1 TB storage, region eu-west-1. Walk through the whole thing.
Agent response pattern (abridged):
Announce reference: "Loading
references/serverless-advisory-instructions.md."Print:
python3 scripts/acu_calculator.py estimate \ --region eu-west-1 \ --instance db.r7g.2xlarge \ --cpu-p95 40 --cpu-max 65 \ --connections 200 --working-set 12 --storage 1000 \ --num-instances 1 --format tableScript output (db.r7g.2xlarge, 8 vCPU): min_ACU 8.0 (working-set floor 12/2 = 6.0 is satisfied), peak_ACU 21.0, max_ACU 27.5 (= max(round_up(21.0 × 1.30), round_up(13.5 × 1.50))), typical_ACU 13.5.
Costs: offline/static mode prices at us-east-1 rates ($0.12/ACU-hr, $0.10/GiB-mo storage) regardless of
--region; only live API mode applies the eu-west-1 rate. Aurora serverless typical 13.5 × $0.12 × 730 = $1,183/mo compute, storage 1000 × $0.10 = $100, total**$1,283/mo**. Provisioned r7g.2xlarge: $1.106 × 730 = $807 + $100 = $907/mo. Recommendation: not_recommended — serverless is ~41% more at this steady load.Memory advisory: your 12 GiB working set means min_ACU MUST be ≥ 6.0 to keep the hot set in memory. min_ACU=8 already satisfies this. If you set min below 6 you will see buffer-cache misses.
Migration approaches:
- In-place (
modify-db-cluster --serverless-v2-scaling-configuration): simplest, fastest; brief restart per instance. Caveats: cluster must already be r6+ generation. - Blue/Green (recommended for production): new Aurora serverless writer built as green environment, tested under live replication, switchover in <1 min. Best rollback path.
- Snapshot restore to a new cluster: full rebuild; longest, but gives you a parallel cluster to test end-to-end.
- In-place (
Parameter group: MUST be an Aurora serverless-compatible parameter group (family
aurora-mysql8.0). DO NOT hardcodeinnodb_buffer_pool_size(Aurora resizes it with ACU) ormax_connections(Aurora derives it from the cluster's maximum ACU; it is static and needs a reboot to change). Override only for well-understood special cases.CloudFormation snippet (Aurora serverless writer):
ClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Family: aurora-mysql8.0 Description: Enforce TLS for Aurora serverless cluster Parameters: require_secure_transport: "ON" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql EngineVersion: "8.0.mysql_aurora.3.08.0" DBClusterParameterGroupName: !Ref ClusterParameterGroup ServerlessV2ScalingConfiguration: MinCapacity: 8.0 MaxCapacity: 27.5 StorageEncrypted: true EnableCloudwatchLogsExports: - error - slowquery - audit WriterInstance: Type: AWS::RDS::DBInstance Properties: DBInstanceClass: db.serverless Engine: aurora-mysql DBClusterIdentifier: !Ref DBClusterCDK snippet (TypeScript):
const parameterGroup = new rds.ParameterGroup(this, "PG", { engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_3_08_0 }), parameters: { "require_secure_transport": "ON" }, }); const cluster = new rds.DatabaseCluster(this, "Cluster", { engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_3_08_0 }), parameterGroup, serverlessV2MinCapacity: 8.0, serverlessV2MaxCapacity: 27.5, writer: rds.ClusterInstance.serverlessV2("Writer"), storageEncrypted: true, cloudwatchLogsExports: ["error", "slowquery", "audit"], });Testing: snapshot-restore to a test cluster first; run full load tests at peak TPS; observe
ServerlessDatabaseCapacityCloudWatch metric to verify ACU actually scales with load.
Scale-to-zero / auto-pause rules
Aurora serverless auto-pause requires MinCapacity: 0 and is incompatible with: RDS Proxy, binary logging (binlog) enabled, Global Database primary, and Zero-ETL integrations. If the user's workload has any of these, you MUST warn them that scale-to-zero cannot be enabled, and instead recommend a non-zero MinCapacity (e.g. 0.5 for dev/test, ≥1.0 for prod). In a multi-AZ cluster, auto-pause still works: the writer and any reader instances with failover priority 0 or 1 pause and resume together (their capacity is tied to the writer), while reader instances with failover priority 2-15 can pause independently. So a reader configured with priority 0/1 will not pause unless the writer also pauses — but the cluster as a whole can still scale to zero. See concepts.md for the complete compatibility matrix.