# Azure MySQL Flexible Server Excessive Backup Retention

> Dev/test MySQL Flexible Servers retaining backups longer than 7 days are flagged by RC-246 when backup storage exceeds the free allowance (100% of provisioned storage). Savings multiply the billable excess GB by the over-retention share and the real per-GB LRS or GRS rate times 730; any missing input makes it abstain.

Source: https://zop.dev/integrations/azure/recommendations/azure-mysql-flexible-server-excessive-backup-retention
Updated: 2026-08-19

---

## Backup storage is free only up to a line

Azure gives a MySQL Flexible Server backup storage free up to 100% of its provisioned
storage size; only backup data beyond that allowance bills per GB. A dev/test server with
long retention quietly walks past the line: each extra retained day adds recovery points,
and once cumulative backup GB exceeds provisioned GB the meter starts. RC-246 exists for
exactly that crossing: a dev/test server holding backups it will never restore, paying for
storage above the free allowance.

## Two facts must both be true

The server must match a dev/test name pattern, and its discoverer-stamped
`backup_retention_days` metadata must exceed 7, the threshold the rule treats as
sufficient for non-production. Production servers are never flagged by this rule
regardless of retention. The retention value comes from the ARM
`properties.backup.backupRetentionDays` field the discoverer writes into metadata; an
earlier revision read it from tags, where no producer ever put it, and could not fire.

## How the dollar figure is assembled

Every component of the saving is real, and each missing component means abstain:

- **Billable excess**: `MySQLBackupStorageUsed` (Azure Monitor, 30-day window) minus the
  provisioned storage size. Non-positive excess → nothing billed → nothing to save →
  abstain.
- **Retention share**: (retentionDays − 7) / retentionDays, the portion of the excess
  attributable to over-retention.
- **Rate**: the per-GB-hour backup-storage rate for the server's redundancy class,
  multiplied by 730 to get a month. The 730× step matters: the pricing layer serves
  storage rates per GB-*hour*, and omitting the conversion once under-reported savings by
  that factor.

The result is capped at the server's monthly cost. No fraction-of-the-bill estimates, no
$0 advisory rows. A missing metric, missing provisioned size, or missing rate all abstain.

## Geo-redundancy roughly doubles the stakes

The discoverer stamps `geo_redundant_backup` for flexible servers; when it reads `enabled`
the rule prices against the GRS backup rate, which is roughly double LRS. When neither
redundancy signal exists, the rule conservatively assumes the cheaper LRS rate. It would
rather understate a saving than inflate one.

## Read your own retention and redundancy

```bash
az mysql flexible-server show \
  --resource-group <rg> --name <server> \
  --query "{retentionDays:backup.backupRetentionDays, geoBackup:backup.geoRedundantBackup, storageGB:storage.storageSizeGb}"
```

Reducing retention takes one setting change under Compute + Storage; recovery points
beyond the new window age out on their own schedule. Confirm nobody depends on the older
restore points before shortening; 7 days is plenty for most dev loops, but not for every
one.
