Azure Blob Storage Lifecycle Management

Automating Tier Transitions and Cleanup


Introduction

Azure Blob Storage lifecycle management provides policy-based automation for transitioning blobs to lower-cost storage tiers and deleting outdated data. Instead of manually managing storage costs or running custom scripts, you can define rules that automatically move blobs to Cool, Archive, or delete them based on age, access patterns, or custom filters. This significantly reduces storage costs while maintaining data retention requirements.

This comprehensive guide covers:

  • Policy fundamentals — Understanding lifecycle management rules
  • Tier options — Hot, Cool, Archive, and Deep Archive
  • Creating policies — Portal, CLI, and ARM templates
  • Filter configuration — Targeting specific blobs
  • Action sequences — Moving through multiple tiers
  • Best practices — Cost optimization and compliance

Understanding Storage Tiers

Tier Comparison

┌─────────────────────────────────────────────────────────────────────┐
│                    STORAGE TIER COMPARISON                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   TIER      COST/GB    ACCESS TIME    USE CASE                      │
│   ────      ─────────   ───────────    ─────────────────────────    │
│   Hot       $0.0184    < 1 ms         Frequently accessed data      │
│   Cool      $0.0100    < 1 second     Infrequent, >30 days old      │
│   Archive   $0.00099   ~hours         Rarely accessed, >180 days    │
│   Deep      $0.00004   ~hours         Compliance, >365 days         │
│   Archive                                                           │
│                                                                     │
│   COST SAVINGS:                                                     │
│   ─────────────                                                     │
│   Hot → Cool:   ~45% savings                                        │
│   Cool → Archive: ~90% savings                                      │
│   Hot → Archive: ~95% savings                                       │
│                                                                     │
│   RETRIEVAL COSTS:                                                  │
│   ────────────────                                                  │
│   Hot:   No retrieval cost                                          │
│   Cool:  $0.01 per GB                                               │
│   Archive: $0.02 per GB + rehydration time                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Tier Transition Flow

┌─────────────────────────────────────────────────────────────────────┐
│                    TIER TRANSITION FLOW                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │                        HOT TIER                             │   │
│   │                   (Active data)                             │   │
│   │                                                             │   │
│   │   Days: 0-30                                                │   │
│   │   Cost: $0.0184/GB                                          │   │
│   └────────────────────────────┬────────────────────────────────┘   │
│                                │                                    │
│                    tierToCool after N days                          │
│                                │                                    │
│                                ▼                                    │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │                       COOL TIER                             │   │
│   │                  (Infrequent access)                        │   │
│   │                                                             │   │
│   │   Days: 30-90 (or custom)                                   │   │
│   │   Cost: $0.0100/GB                                          │   │
│   │   Access: < 1 second                                        │   │
│   └────────────────────────────┬────────────────────────────────┘   │
│                                │                                    │
│                    tierToArchive after N days                       │
│                                │                                    │
│                                ▼                                    │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │                     ARCHIVE TIER                            │   │
│   │                   (Cold storage)                            │   │
│   │                                                             │   │
│   │   Days: 90+                                                 │   │
│   │   Cost: $0.00099/GB                                         │   │
│   │   Access: Hours to rehydrate                                │   │
│   └────────────────────────────┬────────────────────────────────┘   │
│                                │                                    │
│                    delete after N days                              │
│                                ▼                                    │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │                      DELETED                                │   │
│   │                                                             │   │
│   │   Requires soft-delete to recover                           │   │
│   │                                                             │   │
│   └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Create Lifecycle Policy

Using Azure Portal

  1. Navigate to Storage AccountData managementLifecycle management

  2. Click Add rule

  3. Configure:

    • Rule name: archive-old-files
    • Rule scope: Entire storage account or specific containers
    • Blob types: Block blobs, append blobs
  4. Add actions:

    Action 1: Move to cool tier
    → After: 30 days since last modification
    
    Action 2: Move to archive tier
    → After: 90 days since last modification
    
    Action 3: Delete blob
    → After: 365 days since last modification
    
  5. Review and save

JSON Policy Definition

{
  "rules": [
    {
      "name": "archive-logs",
      "enabled": true,
      "type": "Lifecycle",
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["logs/container/", "archive/"]
        },
        "actions": {
          "baseBlob": {
            "tierToCool": {
              "daysAfterModificationGreaterThan": 30
            },
            "tierToArchive": {
              "daysAfterModificationGreaterThan": 90
            },
            "delete": {
              "daysAfterModificationGreaterThan": 365
            },
            "tierToCoolBeforeCreation": {
              "daysAfterCreationGreaterThan": 30
            }
          },
          "snapshot": {
            "delete": {
              "daysAfterCreationGreaterThan": 90
            }
          },
          "version": {
            "delete": {
              "daysAfterCreationGreaterThan": 180
            }
          }
        }
      }
    }
  ]
}

Using Azure CLI

# Create policy from JSON file
az storage account management-policy create \
  --account-name mystorage \
  --resource-group my-rg \
  --policy @lifecycle-policy.json

# Update existing policy
az storage account management-policy update \
  --account-name mystorage \
  --resource-group my-rg \
  --policy @updated-policy.json

# Show current policy
az storage account management-policy show \
  --account-name mystorage \
  --resource-group my-rg

# Delete policy
az storage account management-policy delete \
  --account-name mystorage \
  --resource-group my-rg

Using ARM Template

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts/managementPolicies",
      "apiVersion": "2023-01-01",
      "name": "mystorage/default",
      "properties": {
        "policy": {
          "rules": [
            {
              "name": "cost-optimization",
              "enabled": true,
              "type": "Lifecycle",
              "definition": {
                "filters": {
                  "blobTypes": ["blockBlob"],
                  "prefixMatch": ["container1/", "container2/"]
                },
                "actions": {
                  "baseBlob": {
                    "tierToCool": {
                      "daysAfterModificationGreaterThan": 30
                    },
                    "tierToArchive": {
                      "daysAfterModificationGreaterThan": 90
                    },
                    "delete": {
                      "daysAfterModificationGreaterThan": 365
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  ]
}

Filter Configuration

Prefix-Based Filtering

{
  "rules": [
    {
      "name": "logs-policy",
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": [
            "logs/2024/",
            "archive/backups/"
          ]
        }
      }
    }
  ]
}

Multiple Rules with Different Scopes

{
  "rules": [
    {
      "name": "aggressive-archive",
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["temp/"]
        },
        "actions": {
          "baseBlob": {
            "tierToCool": { "daysAfterModificationGreaterThan": 7 },
            "delete": { "daysAfterModificationGreaterThan": 30 }
          }
        }
      }
    },
    {
      "name": "compliance-archive",
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["compliance/"]
        },
        "actions": {
          "baseBlob": {
            "tierToArchive": { "daysAfterModificationGreaterThan": 365 },
            "delete": { "daysAfterModificationGreaterThan": 2555 }
          }
        }
      }
    }
  ]
}

Action Types

Base Blob Actions

{
  "baseBlob": {
    "tierToCool": {
      "daysAfterModificationGreaterThan": 30
    },
    "tierToArchive": {
      "daysAfterModificationGreaterThan": 90,
      "daysAfterLastAccessTimeGreaterThan": 30
    },
    "tierToCold": {
      "daysAfterModificationGreaterThan": 45
    },
    "delete": {
      "daysAfterModificationGreaterThan": 365
    },
    "enableAutoTierToHotFromCool": true
  }
}

Snapshot Actions

{
  "snapshot": {
    "delete": {
      "daysAfterCreationGreaterThan": 90
    }
  }
}

Version Actions

{
  "version": {
    "delete": {
      "daysAfterCreationGreaterThan": 180
    },
    "tierToArchive": {
      "daysAfterCreationGreaterThan": 90
    }
  }
}

Real-World Examples

Logs Retention Policy

{
  "rules": [
    {
      "name": "logs-retention",
      "enabled": true,
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["logs/"]
        },
        "actions": {
          "baseBlob": {
            "tierToCool": { "daysAfterModificationGreaterThan": 7 },
            "tierToArchive": { "daysAfterModificationGreaterThan": 30 },
            "delete": { "daysAfterModificationGreaterThan": 90 }
          }
        }
      }
    }
  ]
}

Backup Archive Policy

{
  "rules": [
    {
      "name": "backup-archive",
      "enabled": true,
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["backups/"]
        },
        "actions": {
          "baseBlob": {
            "tierToCool": { "daysAfterModificationGreaterThan": 30 },
            "tierToArchive": { "daysAfterModificationGreaterThan": 90 },
            "delete": { "daysAfterModificationGreaterThan": 2555 }
          }
        }
      }
    }
  ]
}

Temporary Files Cleanup

{
  "rules": [
    {
      "name": "temp-cleanup",
      "enabled": true,
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["temp/", "uploads/temp/"]
        },
        "actions": {
          "baseBlob": {
            "delete": { "daysAfterModificationGreaterThan": 7 }
          }
        }
      }
    }
  ]
}

Important Considerations

Policy Behavior

┌─────────────────────────────────────────────────────────────────────┐
│                    POLICY LIMITATIONS                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ✓ Runs once per day (around midnight UTC)                         │
│   ✓ Processes block blobs only (not page blobs)                     │
│   ✓ Works with standard storage accounts (not premium)              │
│   ✓ Cannot be undone - delete is permanent                          │
│   ✓ Soft delete can recover deleted blobs (if enabled)              │
│   ✓ Archive blobs require rehydration before reading                │
│                                                                     │
│   Archive Rehydration:                                              │
│   ────────────────────                                              │
│   1. Change tier to Hot/Cool (takes 1-15 hours)                     │
│   2. Wait for rehydration to complete                               │
│   3. Read the blob                                                  │
│   4. OR use Copy to rehydrate faster                                │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Enabling Soft Delete

# Enable blob soft delete
az storage account update \
  --name mystorage \
  --resource-group my-rg \
  --blob-service-properties '{
    "deleteRetentionPolicy": {
      "enabled": true,
      "days": 30
    }
  }'

Best Practices

Cost Optimization

PracticeDescription
Use tier transitionsMove to cooler tiers as data ages
Set appropriate deletionBalance retention with costs
Enable soft deleteProtect against accidental deletion
Use prefixesTarget specific data for policies

Monitoring

# Check lifecycle management metrics
az monitor metrics list \
  --resource /subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/mystorage \
  --metric "LifecycleManagementTarget"

# View storage account diagnostics
az storage logging update \
  --account-name mystorage \
  --log-level information \
  --read write delete

Related Topics


Azure Integration Hub - Intermediate Level