Skip to main content
rightsizing · azure

Dev/test storage accounts paying the GRS geo-replication premium

resource types
1
rule IDs covered
1
severity
low

What does ZopNight detect here?

ZopNight flags dev/test storage accounts running GRS, RAGRS, GZRS, or RAGZRS replication and prices the switch to LRS as the real per-account premium, (GRS rate − LRS rate) × stored GB. Geo-redundant storage costs roughly 2x the LRS rate. Without a positive measured premium the rule abstains entirely.

Signal and threshold

How ZopNight evaluates Dev/test storage accounts paying the GRS geo-replication premium.
Field Value
Rule IDsRC-1324
Categoryrightsizing
Severitylow
Metricnone — pure configuration read
Sourcestorage_replication.go

Why geo-redundancy is wasted on dev/test data

Geo-redundant storage keeps six copies of every object: three in the primary region and three in an Azure-paired region, asynchronously replicated for regional-disaster survival. Dev/test data rarely deserves that. Build artifacts, test fixtures, and scratch datasets are reproducible by definition: if the region burns down, you regenerate them. Meanwhile the account pays roughly double the LRS rate for a durability guarantee nobody would ever invoke.

Spot geo-redundant dev accounts

Terminal window
az storage account list \
--query "[?contains(sku.name, 'GRS') || contains(sku.name, 'GZRS')].{name:name, sku:sku.name, rg:resourceGroup}" \
-o table

Cross-reference the names against your environment conventions; ZopNight does the same match automatically.

Four gates, all from real data

The rule fires only when every signal aligns. The account name must match a dev/test naming pattern, with infrastructure names such as “devops” explicitly excluded from the match. The discoverer-written replication_type metadata (the last underscore token of the storage SKU) must be GRS, RAGRS, GZRS, or RAGZRS; an absent key means the rule abstains rather than guessing. The aggregator must have supplied a positive monthly cost. And a positive geo-replication premium must have been measured for this specific account.

How the dollar figure is computed

The saving is never a percentage of the bill. The aggregator computes the per-account premium as (GRS rate − base LRS rate) × stored GB, using a measured hot-GRS rate of $0.046 per GB-month from its pricing cache. When the GRS rate is missing from the cache or the stored size is unknown, no premium is emitted and the rule stays silent, a deliberate design that prefers reporting nothing over reporting a fabricated number. The premium is also clamped to the account’s actual cost, so the projected optimized cost can never go negative.

Downgrading and its trade-off

Flipping replication from GRS to LRS in the account’s Configuration blade takes effect without downtime, but the move is a genuine durability reduction: a regional outage now means the data is unavailable until the region recovers, and a regional catastrophe means it is gone. For reproducible dev/test data that trade is usually correct. If an account graduates to production later, flip it back; the change is reversible in both directions.

Detection needs only the built-in Reader role via Azure Resource Graph; the cost inputs come through Cost Management Reader.

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·