Skip to main content
rightsizing · aws

RDS PITR Enabled on Non-Production

resource types
1
rule IDs covered
1
severity
low

What does ZopNight detect here?

Point-in-time recovery on dev/test RDS instances bills backup storage only beyond 100% of provisioned capacity, so savings equal the billable excess GB times the rds-snapshot rate times 730 hours. ZopNight abstains on all live data today because the backup_storage_used metric has no producer yet, and enforces a $5 floor.

Signal and threshold

How ZopNight evaluates RDS PITR Enabled on Non-Production.
Field Value
Rule IDsRC-168
Categoryrightsizing
Severitylow
Metricnone — pure configuration read
Sourcerds_pitr.go

Spotting PITR from the retention period

  • PITR-active gate from Metadata (fail-closed): backupRetentionPeriod>0 (or alias backup_retention_days>0), or the GCP fallback string pitr_enabled=“true”; the prior Tags[“pitr_enabled”] gate was dead (no AWS producer writes it)
  • resource.Name: dev/test pattern (isDevTestName, which already implies !isProdName, so the redundant isProdName check was removed)
  • Metadata[“storage”] (int AllocatedStorage, the free-allowance baseline: backup storage is free up to 100% of provisioned DB storage)
  • PricingAware: per-resource monthly cost
  • Producer-gap backup_storage_used metric (GB-as-bytes of automated-backup storage, AWS/RDS): the CloudWatch series RDS publishes include no native total-backup-storage counter, so it must come from Cost Explorer BackupUsage / a DescribeDBInstanceAutomatedBackups rollup; absent today → the rule abstains
  • SKURatesAware rds-snapshot SKU rate (per-GB backup-storage, RDS:ChargedBackupUsage): already ingested into the aws rate map by the aggregator (pricing/aws/pricing.go), and it is the same key sibling RC-032 (rds_backup_retention.go) resolves. (A prior rds-backup-storage key had zero producers and always resolved to 0; fixed by re-keying onto this live SKU, so no producer work is needed for the rate.)

Billing only backup beyond the free allowance

Concrete or abstain (cost-driven rightsizing). billableGB = max(0, backupUsedGB − provisionedGB), savings = billableGB × perGBHourRate × 730. The rds-snapshot rate from model.LookupSKURate is per-GB-hour (pricing ingest divides the catalog per-GB-month figure by 730; see pricing/aws/stream.go isStorageRate), so the ×730 is mandatory to get a monthly figure (mirrors GCP RC-147). The rule is fail-closed: it returns nil on any missing input (no backup_storage_used metric, the current live gap; no provisioned size; no billable excess; no rate) or below the $5 minSavingsUSD floor. It never emits a $0/advisory rec, and never the prior cost*0.30 fabricated fraction. The prior “performance”/SavingsUSD=0 advisory dodge is removed.

Disabling PITR on a dev database

  1. Confirm this is a non-production database
  2. Modify the RDS instance backup retention period to 0 (disables PITR) or 1 day
  3. Ensure automated snapshots still meet recovery requirements
  4. Consider manual snapshots for longer retention needs

The missing backup storage producer

backup_storage_used (30d, MetricsAware; SKURatesAware: rds-snapshot). The non-prod gate now uses the authoritative env tag (prod-tag hard veto; name only as corroborating fallback), not a name heuristic; abstains on live data until the backup_storage_used metric producer lands (the rds-snapshot rate is already live)

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·