# Azure MySQL Flexible Server Reserved Capacity

> Azure MySQL Flexible Servers with a production name or env tag, 60+ days of history, roughly 70% uptime, and measured MySQLCpuPercent or MySQLMemoryPercent at 30%+ get a reserved-capacity recommendation (RC-245). The saving is a sanity-banded fraction of monthly cost, defaulting to 35%, because raw tier-rate lookups can collide with VM pricing.

Source: https://zop.dev/integrations/azure/recommendations/azure-mysql-flexible-server-reserved-capacity
Updated: 2026-08-19

---

## Why this saving is a bounded fraction, not a raw rate delta

Most commitment rules want to price directly off the reserved-vs-on-demand rate pair. RC-245
deliberately does not. The tier-rate lookup is keyed on the server's raw SKU token, a
VM-style string like "Standard_D2ds_v4", and the rate table is not filtered by service, so
that lookup can silently return the *Virtual Machines* reserved-instance row instead of the
Azure Database for MySQL one. Billing a database commitment at a bare-VM RI rate would be
undetectably wrong. So the dollar figure is cost × a derived discount fraction that is
sanity-checked against a plausibility band and rate-inversion guard, falling back to a fixed
35% when the derived ratio looks unsound. Break-even math is still used, but only as a veto:
when the reservation can be priced and would cost more than current spend, the rule
abstains rather than book a losing commitment.

## The dead-rule history baked into this check

An earlier eligibility gate read the EC2-style metric names CPUUtilization and
MemoryUtilization, names the Azure producer never writes for this resource type, so the
gate reported "utilization unverified" on every real server and the rule abstained 100% of
the time. The fix reads the exact producer-written series, `MySQLCpuPercent` and
`MySQLMemoryPercent`, and declares them so the platform pre-fetches both over a 30-day
window via **Monitoring Reader**.

## Three fail-closed hurdles before recommending a year

- **History**: at least 60 days of observed coverage; unknown coverage abstains.
- **Uptime**: known and at or above the 0.70 commitment floor. A part-time server should be
  scheduled, not committed.
- **Utilization**: a *measured* CPU or memory average at or above 30%. An empty series from
  a stopped server counts as unverified, never as measured 0%.

The server must also carry a production signal (a prod name pattern or an authoritative
environment tag) and must not already be covered by a Reservation, a SavingsPlan, or a
`reserved=true` tag. Missing pricing abstains.

## Confirm which servers are candidates

```bash
az mysql flexible-server list \
  --query "[].{name:name, sku:sku.name, tier:sku.tier, state:state}" -o table
```

Cross-reference the running production servers against your reservations in Portal →
Reservations. Purchasing reserved capacity itself takes billing-account permissions your
own admin holds; ZopNight only reads state (**Reader**, **Cost Management Reader**) and
never buys commitments on your behalf.
