# RDS Dev/Test Burstable Opportunity

> RDS dev/test instances averaging 20% CPU or less over 30 days, without saturation peaks, fit a same-size db.t4g burstable class. ZopNight prices the swap as the live rate delta times 730 hours times measured uptime, and abstains when a RAM-halving swap lacks measured FreeableMemory headroom above the 512 MiB floor.

Source: https://zop.dev/integrations/aws/recommendations/rds-dev-test-burstable-opportunity
Updated: 2026-08-19

---

## Which dev/test databases fit a db.t4g class

- resource.Status: statusAvailable
- Metadata["engine"]: must be a standard RDS engine (isStandardRDSEngine, which excludes Neptune/DocumentDB/Aurora) AND offer a burstable family (engineSupportsBurstable, which excludes Oracle / SQL Server)
- resource.Name: dev/test pattern (prod env-tag is an authoritative VETO)
- already-db.t* classes skipped (already burstable)
- CPUUtilization, taken from [the CloudWatch series RDS publishes per instance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/monitoring-cloudwatch.html), windowed to 30 days (model.WindowMetric): average ≤ rdsBurstableMaxAvgCPU (20%); abstain when the metric is absent (no blind class change off a name). The decision, title, and evidence now describe the same 30-day window (previously the rule read the raw full-range series while the title hard-coded "7 days").
- Peak guard (production audit 2026-06): abstain when the trusted peak (Maximum) is at/above model.PeakUtilizationSafeCeiling. A database that bursts near saturation is not a burstable candidate (it would exhaust db.t CPU credits at peak), regardless of a low average. Evaluated on the full metric; self-disables below MinMaxCoverageDays. Mirrors RC-158/RC-030.
- a nameable same-size db.t4g target via suggestBurstableRDS (abstain when none exists)
- Memory-suitability gate (2026-07 audit, RC-030 parity): suggestBurstableRDS preserves the SIZE token, not the RAM, so a memory-optimized source halves memory on the swap (db.r5.large 16 GiB → db.t4g.large 8 GiB). When the swap is RAM-reducing (or either class RAM is unknown in rdsClassMemoryGiB), the window-minimum FreeableMemory must exceed the removed RAM + RC-030's 512 MiB pressure floor; unknown class RAM, absent series, or insufficient measured headroom => abstain (fail-closed). Memory-preserving db.m* swaps are unaffected. The Description now states the real RAM relation ("keeps the same memory (N GiB)" vs "memory drops from X to Y GiB; measured FreeableMemory shows the database never used the removed headroom") instead of the old unconditional "same memory" claim.
- PricingAware + SKURatesAware (source class rate + db.t4g target rate)

## Pricing the swap as a live rate delta

Concrete compute-rate delta (no advisory/$0 fallback): savings = (srcRate − dstRate) × 730 × measured uptime (UptimeForUID, fail-open to 24×7 when unknown, matching RC-030), capped at cost × (1 − dst/src) (the storage-inclusive ceiling; a class swap never shrinks storage/backup). Both on-demand rates, [the same per-class hourly figures AWS publishes](https://aws.amazon.com/rds/pricing/), are looked up live via model.LookupSKURate (target pre-fetched via TargetSKUCandidates); abstains when either rate is missing or the burstable class is not genuinely cheaper (dst >= src). The prior "$0 advisory (target-class rate not wired)" state is gone; the db.t4g rate is now wired via SetSKURates + TargetSKUCandidates.

## Switching the instance class safely

1. Verify this is a non-production database
2. Check current CPU usage patterns, since burstable instances are ideal for variable workloads
3. Go to RDS Console → Modify → Change instance class to a db.t4g equivalent (Graviton burstable, current-gen; db.t3 is still supported but no longer the default)
4. Monitor CPU credit balance after the change

## CPU and memory, both over 30 days

CPUUtilization + FreeableMemory (both 30-day; SKURatesAware: source + db.t4g target rates)
