Reduce Azure snapshot storage costs by 30-60% through orphaned snapshot cleanup, aged snapshot governance, Premium-to-Standard tier migration, and automated lifecycle management.
Azure managed disk snapshots accumulate silently because no built-in lifecycle policy enforces retention or tier alignment. Unlike blob storage, which supports lifecycle management rules natively, snapshots persist indefinitely once created. The result is a growing pool of storage charges that rarely gets reviewed until someone notices the bill.
Three cost patterns drive the majority of snapshot waste: orphaned snapshots whose source disk has been deleted, aged snapshots that have outlived their recovery value, and over-tiered snapshots stored on Premium_LRS when Standard_LRS would serve the same purpose. Addressing all three typically reduces snapshot storage spend by 30-60%.
Key Takeaways
Azure does not provide a native lifecycle policy for managed disk snapshots. Once created, snapshots persist indefinitely unless explicitly deleted. This creates three compounding cost problems:
Who this impacts:
Financial example:
An organization with 500 snapshots averaging 50 GB each, split between Premium_LRS and Standard_LRS tiers, could be spending approximately $1,062/month on snapshot storage alone. Through orphaned cleanup, tier migration, and aged snapshot governance, this can typically be reduced to under $400/month -- a savings of approximately $12,750 per year.
| SKU | Price (approx.) | Billing Basis |
|---|---|---|
| Standard_LRS | ~$0.05/GB/month | Used data size |
| Standard_ZRS | ~$0.05/GB/month | Used data size |
| Premium_LRS | ~$0.12/GB/month | Used data size |
Important notes:
An orphaned snapshot is one whose source disk has been deleted. The snapshot remains fully billable but can no longer serve its original recovery purpose -- there is no disk to restore to. These snapshots accumulate when VMs are decommissioned, disks are rebuilt, or infrastructure-as-code pipelines tear down environments without cleaning up associated snapshots.
Detection logic:
Snapshot exists
-> Check creationData.sourceResourceId
-> Does the source disk still exist?
-> YES: Not orphaned (evaluate age and tier separately)
-> NO: Orphaned candidate
-> Is snapshot under compliance or legal hold?
-> YES: Retain and tag for review
-> NO: Are there downstream dependencies (images, ASR)?
-> YES: Retain until dependencies are resolved
-> NO: Safe to DELETEDetection via Azure Resource Graph:
resources
| where type == "microsoft.compute/snapshots"
| extend sourceId = tostring(properties.creationData.sourceResourceId)
| join kind=leftanti (
resources
| where type == "microsoft.compute/disks"
| project id
) on $left.sourceId == $right.id
| project name, resourceGroup, subscriptionId,
sku = tostring(sku.name),
sizeGb = tostring(properties.diskSizeGb),
created = tostring(properties.timeCreated),
incremental = tostring(properties.incremental)Key constraint: Before deleting any orphaned snapshot, confirm it is not referenced by Azure Backup (Recovery Services vault), Azure Site Recovery, managed images, or Azure Compute Gallery image versions. Snapshot deletion is irreversible.
Snapshots older than 30 days should be reviewed against active retention requirements. Most operational snapshots (pre-patching, pre-deployment, troubleshooting) lose their recovery value within days. Yet without a lifecycle policy, they persist for months or years, quietly accumulating charges.
Decision tree:
Snapshot age > threshold (e.g., 30 days)
-> Is snapshot under legal or compliance hold?
-> YES: Retain, tag with retention expiry date
-> NO: Is snapshot covered by Azure Backup or a newer snapshot?
-> YES: Redundant -- safe to DELETE
-> NO: Does any active workload depend on this snapshot?
-> YES: Retain until dependency is resolved
-> NO: Does long-term archival make sense?
-> YES: Export to blob storage (Cool or Archive tier)
-> NO: Safe to DELETEArchival path -- why blob export matters:
Managed disk snapshots are stored as page blobs and do not support Cool or Archive access tiers. To achieve long-term archival savings, you must export the snapshot to a block blob in a storage account, then apply lifecycle management rules to move it to Cool or Archive tier.
| Storage Option | Cost per GB/month | Savings vs Standard Snapshot |
|---|---|---|
| Standard Snapshot (Standard_LRS) | $0.050 | Baseline |
| Cool Blob Storage | $0.010 | 80% cheaper |
| Archive Blob Storage | $0.001 | 98% cheaper |
Example: A 100 GB snapshot held for 1 year costs $60 as a Standard snapshot, $12 in Cool blob storage, or $1.20 in Archive blob storage.
Export process:
# Generate SAS URI for snapshot export
az snapshot grant-access --name snapshotName \
--resource-group rg --duration-in-seconds 3600 --access-level Read
# Copy snapshot to block blob in target storage account
az storage blob copy start \
--destination-blob snapshot-export.vhd \
--destination-container archives \
--account-name archiveStorageAccount \
--source-uri "<SAS-URI-from-previous-step>"
# After copy completes, move blob to Archive tier
az storage blob set-tier \
--account-name archiveStorageAccount \
--container-name archives \
--name snapshot-export.vhd \
--tier Archive
# Delete the original snapshot
az snapshot delete --name snapshotName --resource-group rgKey constraint: Rehydrating from Archive tier takes hours (standard priority) or up to 15 hours (high priority). Do not archive snapshots that may be needed for rapid recovery scenarios.
Premium_LRS snapshots cost $0.12/GB/month compared to $0.05/GB/month for Standard_LRS -- a 2.4x cost multiplier. Snapshots inherit the source disk's SKU by default, meaning every snapshot of a Premium disk is automatically created at the Premium rate unless explicitly overridden.
Financial example:
100 snapshots at 50 GB each: Premium_LRS costs $600/month vs Standard_LRS at $250/month. Migrating to Standard saves $350/month or $4,200/year -- a 58% reduction with no impact on data integrity.
Decision tree:
Snapshot SKU == Premium_LRS
-> Does this snapshot require sub-minute restore (fast RTO)?
-> YES: Retain on Premium_LRS
-> NO: Does the workload require zone redundancy?
-> YES: Consider Standard_ZRS (same price as Standard_LRS)
-> NO: Migrate to Standard_LRSMigration commands:
# List all Premium snapshots
az snapshot list --query "[?sku.name=='Premium_LRS']" \
--output table
# For full (non-incremental) snapshots: in-place SKU update
az snapshot update --name snapshotName \
--resource-group rg --sku Standard_LRS
# For incremental snapshots: create new Standard snapshot from source
# (cannot change SKU in-place on incremental snapshots)
az snapshot create --name snapshotName-std \
--resource-group rg \
--source "/subscriptions/.../disks/sourceDisk" \
--incremental --sku Standard_LRS
# Verify and delete original Premium incremental snapshot
az snapshot delete --name snapshotName --resource-group rgWarning: Changing the SKU on an incremental snapshot can reset the incremental chain. For incremental snapshots, create a new Standard_LRS incremental snapshot from the source disk instead of modifying the existing one. This preserves the chain integrity for remaining snapshots.
The following PowerShell runbook can be deployed to Azure Automation with a weekly schedule. It identifies orphaned, aged, and Premium-tier snapshots across all subscriptions and optionally deletes orphaned snapshots with a DryRun safety mode.
# Runbook: Manage-SnapshotLifecycle
# Schedule: Weekly
# Parameters
param(
[int]$AgeThresholdDays = 30,
[bool]$DeleteOrphaned = $false,
[bool]$DryRun = $true
)
# Connect via managed identity
Connect-AzAccount -Identity
# Get all snapshots and disks across subscriptions
$snapshots = Get-AzSnapshot
$disks = Get-AzDisk
$diskIds = $disks | ForEach-Object { $_.Id.ToLower() }
$orphaned = @()
$aged = @()
$premiumCandidates = @()
foreach ($snap in $snapshots) {
$sourceId = $snap.CreationData.SourceResourceId
$isOrphaned = $false
# Check if source disk still exists
if ($sourceId -and ($diskIds -notcontains $sourceId.ToLower())) {
$isOrphaned = $true
$orphaned += $snap
}
# Check age
$snapAge = (Get-Date) - $snap.TimeCreated
if ($snapAge.TotalDays -gt $AgeThresholdDays) {
$aged += $snap
}
# Check for Premium tier
if ($snap.Sku.Name -eq "Premium_LRS") {
$premiumCandidates += $snap
}
}
# Report
Write-Output "=== Snapshot Lifecycle Report ==="
Write-Output "Total snapshots: $($snapshots.Count)"
Write-Output "Orphaned snapshots: $($orphaned.Count)"
Write-Output "Aged snapshots (>$AgeThresholdDays days): $($aged.Count)"
Write-Output "Premium_LRS candidates: $($premiumCandidates.Count)"
Write-Output ""
# Estimate orphaned cost
$orphanedCost = ($orphaned | ForEach-Object {
$size = $_.DiskSizeGB
$rate = if ($_.Sku.Name -eq "Premium_LRS") { 0.12 } else { 0.05 }
$size * $rate
} | Measure-Object -Sum).Sum
Write-Output "Estimated orphaned snapshot monthly cost: $$orphanedCost"
# Optional deletion for orphaned snapshots
if ($DeleteOrphaned -and $orphaned.Count -gt 0) {
foreach ($snap in $orphaned) {
if ($DryRun) {
Write-Output "[DRY RUN] Would delete: $($snap.Name) " +
"in $($snap.ResourceGroupName) " +
"(SKU: $($snap.Sku.Name), Size: $($snap.DiskSizeGB) GB)"
} else {
Write-Output "Deleting: $($snap.Name) in $($snap.ResourceGroupName)"
Remove-AzSnapshot -ResourceGroupName $snap.ResourceGroupName \
-SnapshotName $snap.Name -Force
}
}
}
Write-Output "=== Report Complete ==="Key constraint: Always run with $DryRun = $true first to review candidates before enabling deletion. The runbook does not check for Azure Backup vault dependencies -- validate those separately before enabling $DeleteOrphaned.
Snapshots are billed based on the used data size of the source disk at the time the snapshot was taken, not the provisioned disk size. Standard_LRS and Standard_ZRS snapshots cost approximately $0.05/GB/month, while Premium_LRS snapshots cost approximately $0.12/GB/month. Incremental snapshots bill only for the delta changes since the previous snapshot, which can significantly reduce per-snapshot costs for disks with low change rates.
Deleting a snapshot that is part of an Azure Backup incremental chain can break the recovery point sequence, potentially making one or more restore points unrecoverable. Always check Recovery Services vault associations and backup policies before deleting any snapshot. Azure Backup manages its own snapshot lifecycle -- manually deleting Backup-managed snapshots can cause data loss.
No. Snapshots are independent copies of the disk data at a point in time. Deleting a snapshot has no impact on the source disk, any VMs using that disk, or the disk's data. The only risk is losing the ability to restore to that specific point in time.
For full (non-incremental) snapshots, yes -- you can update the SKU in-place using az snapshot update --sku Standard_LRS. For incremental snapshots, you cannot change the SKU in-place. Instead, create a new Standard_LRS incremental snapshot from the source disk and delete the original Premium snapshot after verification.
No. Unlike blob storage, managed disk snapshots do not have a native soft delete feature. Once a snapshot is deleted, it cannot be recovered. To protect against accidental deletion, use Azure resource locks (CanNotDelete) on critical snapshots, or rely on Azure Backup which manages its own retention and soft delete for backup-created snapshots.
Both incremental and full snapshots are billed at the same per-GB rate for their respective SKU. The difference is in how much data they store. Full snapshots capture all used data on the disk regardless of previous snapshots. Incremental snapshots store only the blocks that changed since the previous snapshot, which means they typically use far less storage and cost less in total -- even though the per-GB rate is identical.
Use the Azure Resource Graph query provided in this article. Resource Graph queries run across all subscriptions the caller has access to in a single call, without needing to switch context. For MSPs using Azure Lighthouse, the query works across all delegated subscriptions automatically.
Standard_LRS and Standard_ZRS snapshots are priced identically at approximately $0.05/GB/month. The difference is redundancy: LRS stores three copies within a single data center, while ZRS replicates across three availability zones in the region. Choose ZRS when zone-level protection for snapshot data is required; otherwise, LRS is sufficient and equally priced.
No. Managed disk snapshots are stored as page blobs and do not support access tier changes. To achieve Archive-tier pricing (approximately $0.001/GB/month -- 98% cheaper than Standard snapshots), you must export the snapshot to a block blob using a SAS URI, copy it to a storage account, and then set the blob tier to Archive. Be aware that rehydrating from Archive takes hours and incurs retrieval fees.
Implement a combination of controls: enforce tagging policies (owner, expiry date, purpose) on all snapshots via Azure Policy, deploy the automation runbook for weekly lifecycle reviews, set default SKU to Standard_LRS in IaC templates (Terraform, Bicep, ARM), and use incremental snapshots by default to minimize per-snapshot storage volume.
Instant Access is a feature for incremental snapshots that enables sub-second restore times by keeping the snapshot data readily accessible. It is currently free until July 2026, after which Microsoft will begin charging for the Instant Access tier. If your snapshots do not require sub-second restore, plan to evaluate the cost impact before the free period ends.
Before
$12,000/mo
3,200 snapshots across 20 tenants, mix of Premium and Standard, no lifecycle policy
After
$4,320/mo
Reduced to 1,440 snapshots after orphaned cleanup, tier migration, and age-based deletion
Actions taken: Deployed Resource Graph query across all Lighthouse-delegated subscriptions. Identified 1,100 orphaned snapshots, 660 aged snapshots beyond retention windows, and migrated 380 Premium snapshots to Standard_LRS. Automated weekly lifecycle runbook deployed per tenant.
Before
$2,700/mo
1,800 pipeline snapshots created for deployment rollback, none cleaned up
After
$67.50/mo
Retained only 45 snapshots covering active release branches
Actions taken: Audited all pipeline-created snapshots. Found 97.5% were for releases already superseded. Implemented 7-day retention policy for pipeline snapshots via automation, with exceptions for current production and N-1 release only.
Before
$20,000/mo
5,000 snapshots retained for regulatory compliance, all on Standard_LRS
After
$1,184/mo
Exported to Archive blob storage, retaining only 30-day operational snapshots natively
Actions taken: Classified snapshots by age and compliance requirement. Snapshots older than 30 days exported to Archive blob storage at $0.001/GB/month. Retained 200 recent snapshots on Standard_LRS for operational recovery. Documented export process for compliance audit trail.
Before
$1,440/mo
300 snapshots on Premium_LRS (inherited from Premium disk defaults)
After
$600/mo
Migrated all snapshots to Standard_LRS, updated IaC defaults
Actions taken: Identified that all 300 snapshots inherited Premium_LRS from source disks. No workload required sub-minute snapshot restore. Migrated full snapshots in-place and recreated incremental snapshots at Standard_LRS. Updated Terraform modules to default snapshot SKU to Standard_LRS.
| Action | Typical Savings | Complexity |
|---|---|---|
| Delete orphaned snapshots | 100% of orphan cost | Low |
| Delete aged snapshots (>30d) | 10-30% of total | Low |
| Premium to Standard migration | ~58% per snapshot | Medium |
| Export to Archive blob storage | ~98% per snapshot | Medium |
| Switch to incremental snapshots | 50-90% per new snapshot | Low |
| Combined approach | 30-60% of total spend | Medium |
The challenges outlined in this article — orphaned snapshot accumulation, Premium tier waste on backup storage, aged snapshots persisting without lifecycle controls — are the same ones our customers work through across their Azure environments. The difference is they use Spotto to surface these opportunities automatically, rather than running the analysis by hand.
Spotto continuously monitors snapshot lifecycle across your Azure subscriptions -- identifying orphaned snapshots, flagging Premium-tier waste, tracking aged snapshots against retention policies, and surfacing archive migration opportunities so you can eliminate waste without losing critical recovery points.
Free TrialDisclaimer: This article is provided for informational purposes only and does not constitute professional advice. Azure pricing, features, and service behavior may have changed since publication. Always validate recommendations against your specific environment and consult Microsoft's official documentation before making changes to production infrastructure. Spotto is not liable for any actions taken based on the content of this article.