# Azure Cosmos DB Provisioned Throughput Rightsizing

> Cosmos DB accounts on manual provisioned throughput are right-sized when normalized RU consumption averages under 10% across 30 days. Target RU/s adds 20% burst headroom over the derived peak, snaps to the 100-RU grid, and floors at 400; savings scale linearly with the RU reduction. Autoscale accounts are skipped.

Source: https://zop.dev/integrations/azure/recommendations/azure-cosmos-db-provisioned-throughput-rightsizing
Updated: 2026-08-19

---

## Manual-throughput accounts under 10% normalized RU

- MetricsAware: name-keyed CosmosNormalizedRU series (read via uid:CosmosNormalizedRU, not bare-UID, since cosmosdb harvests ~10 metrics). Fires when windowed avg \< 10%. CosmosTotalRequests corroborates in the evidence panel.
- metadata: provisioned_ru (provider-authoritative current RU/s, stamped by the discoverer's applyCosmosLookupSets). Absent → abstain (producer gap).
- metadata: cosmos_throughput_mode (manual | autoscale), co-stamped with provisioned_ru from the same throughputSettings rows (fetchCosmosThroughput, one ARG query). The rule fires only when mode == manual, and abstains on autoscale and on an absent/unknown mode (fail-closed). See the manual-vs-autoscale note below.
- peakRU is derived: NormalizedRU is a percent-of-provisioned series, so peakRU = currRU × m.Maximum/100, gated on HasSufficientMaxCoverage (≥7d true-max) so a smoothed peak can't under-size and risk throttling. (NormalizedRU is the *max across partition key ranges*, so under partition skew this over-estimates aggregate peak, a safe and conservative direction that errs toward abstaining.)
- suggestSmallerCosmosRU(currRU, peakRU) sizes the target (peak + 20% burst, snapped to the 100-RU grid, floored at 400); refuses (→ abstain) when no safe smaller RU exists.

## Why RU cuts translate linearly into dollars

The ratio is the real RU reduction: Cosmos bills linearly per 100 RU/s, so SavingsUSD = cost × (currRU − targetRU)/currRU. The hardcoded azureRightsizingSavingsFraction was removed from both paths; this cost-driven rightsizing rec abstains (returns nil) whenever the saving cannot be quantified (no metric, no provisioned_ru, non-manual/unknown throughput mode, insufficient max coverage, or no safe smaller RU). There is no $0 advisory and no fabricated fraction (2026-06-27).

## Checking RU consumption before resizing

1. Review RU consumption metrics in Azure Monitor (Normalized RU Consumption)

## Normalized RU with total requests alongside

CosmosNormalizedRU + CosmosTotalRequests (30d)
