Skip to main content

Theoretical Foundation: Configure Storage Tiers


1. Initial Intuition​

Imagine you manage an office with three types of documents: those you use daily stay on your desk (immediate access, but expensive space); those you consult once a month stay in a file cabinet down the hall (a bit slower, but cheaper); and historical documents from 10 years ago stay in an external warehouse (rarely accessed, minimal storage cost, but takes time to retrieve).

Storage tiers in Azure Blob Storage work exactly like this. Azure offers different "storage shelves" with distinct prices and access characteristics. You place each blob on the appropriate shelf according to its usage pattern, paying less for storage when data is rarely accessed and less for access when data is frequently queried.

The central issue is always a balance between storage cost and access cost.


2. Context​

2.1 Why storage tiers exist​

Data storage has a fundamental economic problem: data grows forever, but not all data has the same value over time. Today's application log is critical now but probably will never be read again in 2 years. A 2019 invoice needs to exist for regulatory reasons but is rarely accessed.

Without tiers, you would pay the same price for petabytes of historical data as for active data, which would make cloud storage economically unfeasible for many organizations.

2.2 Where tiers apply​

Storage tiers are an exclusive feature of Azure Blob Storage (including ADLS Gen2). They do not apply to:

  • Azure Files (which has its own layers: Transaction Optimized, Hot, Cool)
  • Queue Storage
  • Table Storage
  • Azure Managed Disks

Tiers apply only to Block Blobs. Append Blobs and Page Blobs do not support all layers.

2.3 Two levels of tier configuration​

This is a frequent point of confusion: tiers can be defined in two different places:

Storage Account level: Defines the default tier for new blobs that don't specify an explicit tier. Can be Hot or Cool (not Archive).

Individual blob level: Each blob can have a different tier from the account default. This configuration overrides the account default for that specific blob.


3. Building the Concepts​

3.1 The four tiers​

Azure Blob Storage offers four access tiers for Block Blobs:

Hot:

  • Optimized for frequently accessed data
  • Higher storage cost per GB
  • Lower cost for read and write operations
  • Immediate access (milliseconds)
  • Default for new Storage Accounts

Cool:

  • Optimized for infrequently accessed data
  • Lower storage cost than Hot
  • Higher operation cost than Hot
  • Immediate access (milliseconds)
  • Data must remain for at least 30 days (early deletion penalty)

Cold:

  • Intermediate tier between Cool and Archive
  • Lower storage cost than Cool
  • Immediate access (milliseconds)
  • Data must remain for at least 90 days (early deletion penalty)

Archive:

  • Optimized for rarely or never accessed data
  • Lowest storage cost available in Azure
  • Access requires rehydration (process that can take hours)
  • Data must remain for at least 180 days (early deletion penalty)
  • The blob is offline in this tier (cannot be read directly)

3.2 Early Deletion Penalty​

Each tier has an expected minimum storage duration. If you remove or move a blob before this period, you are charged for the remaining time:

TierMinimum periodPenalty if deleted before
HotNoneNone
Cool30 daysCharged for remaining days to 30
Cold90 daysCharged for remaining days to 90
Archive180 daysCharged for remaining days to 180

Practical example: You move a blob to Archive and 30 days later decide to rehydrate it to Hot and delete it. You will be charged for 150 days of Archive storage (the minimum 180 days minus the 30 already elapsed).


3.3 Archive: offline behavior​

The Archive tier is fundamentally different from the others. When a blob is in Archive, it doesn't exist on "online" media. It's on tape storage or very low-cost media. To access it:

  1. You initiate rehydration (hydration): request that the blob be moved from Archive to Hot or Cool.
  2. Azure processes the rehydration with one of two priorities:
    • Standard: 1 to 15 hours (no additional cost)
    • High: less than 1 hour for blobs up to 10 GB (significant additional cost)
  3. After rehydration, the blob becomes normally available in the destination tier.
100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Non-obvious behavior: There's an alternative to traditional rehydration. You can use the Copy Blob operation to copy a blob from Archive directly to a new blob in Hot or Cool, without moving the original. The original blob remains in Archive, and the copy becomes available when the copy/rehydration operation completes. This is useful when you want to keep the file in Archive and just do a one-time read.


3.4 The relationship between account tier and blob tier​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

The account tier is just the default. Each blob can have its own tier defined independently.


3.5 Availability by account type​

Not all tiers are available in all Storage Account types:

TierStandard GPv2Premium Block BlobStandard GPv1
HotYesHot onlyYes
CoolYesNoNo
ColdYesNoNo
ArchiveYesNoNo

Why GPv2 is the recommended default: It's the only type that supports all four tiers. Premium accounts have superior performance but lose cost flexibility via tiers.


4. Structural View: Cost vs Access​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

The arrow represents the direction of decreasing storage cost and increasing access cost.


5. Practical Operation​

5.1 Changing a blob's tier individually​

Tier change is a metadata operation (except for Archive, which is offline). The Set Blob Tier operation instructs the service to move the blob to the new layer.

From Hot/Cool/Cold to Archive: The blob becomes offline progressively (may take a few hours for the process to complete internally).

From Archive to anything: Requires rehydration, which is an asynchronous process.

Between Hot, Cool and Cold: Immediate transition.


5.2 Lifecycle Management: tier automation​

In practice, you don't change tiers manually blob by blob. You define Lifecycle Management Policies that do this automatically based on time rules.

A lifecycle policy defines rules with:

  • Filters: Which blobs the rule applies to (by type, container, prefix, creation date)
  • Actions: What to do (move to Cool, Cold, Archive, delete)
  • Conditions: When to do it (after X days since modification, creation, or last access)
100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

5.3 Last Access Time Tracking​

By default, lifecycle policies base their conditions on the blob's last modification date. However, a blob may not be modified but be frequently read (e.g., a static report that many people access).

Azure offers Last Access Time Tracking: when enabled, the system records the last time the blob was read, not just modified. Lifecycle policies can then use daysAfterLastAccessTimeGreaterThan to make decisions based on actual access.

Cost of Last Access Time Tracking: Enabling this feature adds a small transaction overhead on each blob read. Evaluate the additional cost versus the benefit of more precise tiering.

# Enable Last Access Time Tracking
az storage account blob-service-properties update \
--account-name myaccount \
--resource-group myRG \
--enable-last-access-tracking true

6. Implementation Methods​

6.1 Azure Portal​

Changing a blob's tier individually: Storage Account > Containers > [container] > [blob] > Change tier

The portal presents a dropdown with available options and informs the rehydration priority if the blob is in Archive.

Configuring Lifecycle Management Policy: Storage Account > Data Management > Lifecycle Management > Add rule

The portal offers a visual interface to build rules with filters and actions, without needing to write JSON.

Limitations: Doesn't allow bulk tier changes via portal (only blob by blob).


6.2 Azure CLI​

Changing a blob's tier:

# Hot to Cool
az storage blob set-tier \
--account-name myaccount \
--container-name backups \
--name backup-2024-01.bak \
--tier Cool \
--auth-mode login

# Any layer to Archive
az storage blob set-tier \
--account-name myaccount \
--container-name backups \
--name backup-2022-01.bak \
--tier Archive \
--auth-mode login

# Rehydration from Archive to Hot (Standard priority)
az storage blob set-tier \
--account-name myaccount \
--container-name backups \
--name backup-2022-01.bak \
--tier Hot \
--rehydrate-priority Standard \
--auth-mode login

# Rehydration with High priority (faster, more expensive)
az storage blob set-tier \
--account-name myaccount \
--container-name backups \
--name backup-2022-01.bak \
--tier Hot \
--rehydrate-priority High \
--auth-mode login

Checking rehydration status:

az storage blob show \
--account-name myaccount \
--container-name backups \
--name backup-2022-01.bak \
--auth-mode login \
--query "properties.archiveStatus"

The archiveStatus field returns:

  • null: blob is not in Archive nor in rehydration
  • rehydrate-pending-to-hot: rehydration to Hot in progress
  • rehydrate-pending-to-cool: rehydration to Cool in progress

6.3 Configuring Lifecycle Management via CLI​

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

Example lifecycle-policy.json file:

{
"rules": [
{
"name": "backup-tiering",
"enabled": true,
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["backups/"]
},
"actions": {
"baseBlob": {
"tierToCool": {
"daysAfterModificationGreaterThan": 30
},
"tierToCold": {
"daysAfterModificationGreaterThan": 90
},
"tierToArchive": {
"daysAfterModificationGreaterThan": 180
},
"delete": {
"daysAfterModificationGreaterThan": 2555
}
},
"snapshot": {
"tierToArchive": {
"daysAfterCreationGreaterThan": 90
},
"delete": {
"daysAfterCreationGreaterThan": 365
}
},
"version": {
"tierToArchive": {
"daysAfterCreationGreaterThan": 90
},
"delete": {
"daysAfterCreationGreaterThan": 365
}
}
}
}
}
]
}

6.4 Using Last Access Time in lifecycle policy​

{
"rules": [
{
"name": "access-based-tiering",
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": ["blockBlob"]
},
"actions": {
"baseBlob": {
"tierToCool": {
"daysAfterLastAccessTimeGreaterThan": 30
},
"tierToArchive": {
"daysAfterLastAccessTimeGreaterThan": 180
}
}
}
}
}
]
}

6.5 Azure PowerShell​

$ctx = New-AzStorageContext `
-StorageAccountName "myaccount" `
-UseConnectedAccount

# Change blob tier
$blob = Get-AzStorageBlob `
-Container "backups" `
-Blob "backup-2024-01.bak" `
-Context $ctx

$blob.ICloudBlob.SetStandardBlobTier("Cool")

# Change account default tier
Set-AzStorageAccount `
-ResourceGroupName "myRG" `
-Name "myaccount" `
-AccessTier Cool

6.6 Bicep: configuring lifecycle policy​

resource lifecyclePolicy 'Microsoft.Storage/storageAccounts/managementPolicies@2023-01-01' = {
name: '${storageAccount.name}/default'
properties: {
policy: {
rules: [
{
name: 'backup-tiering'
enabled: true
type: 'Lifecycle'
definition: {
filters: {
blobTypes: ['blockBlob']
prefixMatch: ['backups/']
}
actions: {
baseBlob: {
tierToCool: { daysAfterModificationGreaterThan: 30 }
tierToArchive: { daysAfterModificationGreaterThan: 180 }
delete: { daysAfterModificationGreaterThan: 2555 }
}
}
}
}
]
}
}
}

7. Control and Security​

7.1 Permissions for tier changes​

Changing a blob's tier is a data plane operation. Requires:

Auth methodRequired permission
Azure AD (RBAC)Storage Blob Data Contributor or Owner
Storage Account KeyFull access
SAS tokenw (write) permission on the blob

Important point: The Set Blob Tier operation is considered a write on the blob (modifies its metadata). A SAS with only r (read) permission cannot change the tier.


7.2 Permissions for Lifecycle Management Policy​

Lifecycle Management Policy is a control plane configuration of the Storage Account. Requires:

RoleCan create/edit policy?
Storage Account ContributorYes
OwnerYes
Storage Blob Data ContributorNo
ReaderNo

Note that Storage Blob Data Contributor cannot create lifecycle policies. A control plane role is required.


7.3 Security considerations with Archive​

Data in Archive stays on long-term media. Before archiving sensitive data, consider:

  • Encryption at rest remains active in Archive (AES-256).
  • If using Customer Managed Keys (CMK), key revocation makes data in Archive also inaccessible.
  • The rehydration process doesn't bypass any firewall configuration or Private Endpoint.

8. Decision Making​

8.1 Which tier for each situation​

SituationRecommended tierReason
Active production application dataHotFrequent access, minimal latency
Last 30 days backupsHot or CoolOccasional access for restore
Last 90 days audit logsCoolRare access, but possible
Regulatory data 1 to 7 yearsCold or ArchiveVery rare access, but mandatory retention
Historical backups older than 6 monthsArchiveRarely accessed, minimal cost
Website assets served via CDNHotFrequent access by end users
Rarely used ML datasetsColdSporadic training
10-year compliance dataArchive + ImmutabilityLowest cost + regulatory protection
Yesterday's surveillance videosHotMay be accessed for investigation
6-month-old surveillance videosArchiveRarely accessed

8.2 Rehydration: Standard vs High Priority​

SituationPriorityReason
Backup restore for critical disasterHighTime is critical, cost is secondary
Planned access to historical dataStandardLower cost, hours of latency is acceptable
Regulatory audit with weeks deadlineStandardNo urgency, significant savings
Active security incident investigationHighEvery hour matters

8.3 Last Access Time Tracking: when to enable​

SituationEnable?Reason
Blobs with variable access patternYesTiering based on actual access, not modification
Write-once blobs (logs, backups)Not necessarilyModification and access coincide at upload
Account with high read volumeEvaluate costTransaction overhead per read may exceed savings
Account with few accesses but varied dataYesPrecise tiering with minimal overhead

9. Best Practices​

  • Configure Lifecycle Management Policies as first action when creating Storage Accounts with data that has defined lifecycle. Don't wait to accumulate data to then define rules.
  • Use prefixes to segment data with different lifecycles within the same container. For example: logs/app/, logs/audit/, backups/daily/, backups/monthly/ allow different policies per prefix.
  • Include actions on snapshots and versions in lifecycle policies. Forgetting to delete old snapshots is a common source of unexpected costs.
  • Test lifecycle policies in a test container with manipulated dates before applying to production. Policies are executed once daily and the first cycle may take 24-48h after creation.
  • Avoid Archive for data that may be accessed within 180 days. Early deletion penalty and High Priority rehydration cost may exceed storage savings.
  • Use daysAfterLastAccessTimeGreaterThan instead of daysAfterModificationGreaterThan for data that is frequently read but rarely modified (e.g., static reports).
  • Monitor BlobCapacity by tier to validate policies are working and tier distribution is as expected.
  • Consider transaction costs when designing tiers for high-volume workloads. For many small requests, transaction costs in Cool may exceed storage savings.

10. Common Errors​

ErrorWhy it happensHow to avoid
Unexpected cost when moving blobs from Archive before 180 daysEarly deletion penalty not consideredCalculate TCO including penalties before archiving
Blob in Archive cannot be read after rehydrationRehydration still in progressCheck archiveStatus before attempting to read
Lifecycle policy doesn't apply to existing blobs on first dayPolicies have up to 48h delay after creationCreate policy in advance; wait for complete cycle
Snapshots and versions remain in Hot after lifecycle policyPolicy doesn't include actions for snapshot and versionAlways include snapshot and version sections in policy
Last Access Time Tracking cost exceeds savingsAccount with high read volumeCalculate overhead before enabling
Data in Cool deleted before 30 daysShort lifecycle data moved to CoolAppropriate tier for actual data lifecycle
Archive not available in Premium accountPremium doesn't support ArchiveUse Standard GPv2 for data requiring Archive
High Priority rehydration not available for blobs > 10 GBSize limit for High PriorityUse Standard for large blobs or split into smaller parts

11. Operation and Maintenance​

11.1 Monitoring tier distribution​

In Azure Monitor, filter metrics by BlobCapacity with the Tier dimension:

az monitor metrics list \
--resource <storage-account-id> \
--metric BlobCapacity \
--dimension Tier \
--interval PT1H

This returns capacity separated by Hot, Cool, Cold, and Archive, allowing validation that lifecycle policies are moving data as expected.


11.2 Checking lifecycle policy status​

# View current policy
az storage account management-policy show \
--account-name myaccount \
--resource-group myRG

# View last policy execution
az storage account management-policy show \
--account-name myaccount \
--resource-group myRG \
--query "lastModifiedTime"

Lifecycle policies are executed once daily. There's no detailed log of which blobs were moved in each execution (use Change Feed or Diagnostic Logs for granular tracking).


11.3 Important limits and behaviors​

AspectDetail
Lifecycle policy execution frequencyOnce daily (approximately)
Delay after policy creationUp to 48 hours for first execution
Maximum rules per lifecycle policy100
High Priority rehydration: maximum size10 GB per blob
Standard rehydration: estimated time1 to 15 hours
Cancel ongoing rehydrationPossible: move blob back to Archive
Archive available in which regionsAlmost all regions; check specific availability
Account default tier: optionsOnly Hot or Cool (not Cold or Archive)

12. Integration and Automation​

12.1 Azure Data Factory with tiers​

Azure Data Factory pipelines that process Blob Storage data can define destination tier directly in the copy activity:

{
"sink": {
"type": "BlobSink",
"blobWriterAddHeader": false,
"writeBehavior": "insert"
},
"storeSettings": {
"type": "AzureBlobStorageWriteSettings",
"blockBlobTier": "Cool"
}
}

12.2 Automation with Azure Functions and Event Grid​

For conditional tiering based on business logic (not just time):

import azure.functions as func
from azure.storage.blob import BlobServiceClient

def main(event: func.EventGridEvent):
blob_url = event.get_json()['url']

# Business logic: if blob is larger than 1GB, move to Cool
client = BlobServiceClient.from_connection_string(conn_str)
blob_client = client.get_blob_client(container="data", blob=blob_name)

props = blob_client.get_blob_properties()
if props.size > 1_073_741_824: # 1 GB
blob_client.set_standard_blob_tier("Cool")

12.3 Monitoring Archive with Azure Monitor Alerts​

Configure alerts to detect when Archive volume grows faster than expected (possible lifecycle policy bug):

az monitor metrics alert create \
--name "archive-growth-alert" \
--resource-group myRG \
--scopes <storage-account-id> \
--condition "avg BlobCapacity > 1000000000000" \
--condition-dimension Tier=Archive \
--window-size 1d \
--action myActionGroup

13. Final Summary​

Essential concepts:

  • Storage tiers balance storage cost against access cost: Hot is expensive to store but cheap to access; Archive is cheap to store but expensive and slow to access.
  • There are four tiers for Block Blobs in Standard GPv2: Hot, Cool, Cold and Archive.
  • The tier can be defined at account level (default for new blobs) or individual blob level (overrides account default).
  • Archive is the only offline tier: blobs cannot be read without prior rehydration.

Critical differences:

  • Cool vs Cold vs Archive: Cool = 30-day minimum, immediate access. Cold = 90-day minimum, immediate access. Archive = 180-day minimum, access with hours of wait.
  • Standard vs High rehydration: Standard takes 1-15 hours with no extra cost. High takes less than 1 hour with additional cost and only for blobs up to 10 GB.
  • daysAfterModificationGreaterThan vs daysAfterLastAccessTimeGreaterThan: The first counts since last write. The second (requires Last Access Time Tracking) counts since last read or write.
  • Control plane lifecycle policy: Only roles like Storage Account Contributor can create/edit policies. Storage Blob Data Contributor doesn't have this permission.

What needs to be remembered:

  • Archive is not available in Premium Block Blob accounts (only Standard GPv2).
  • Early deletion penalty is charged if blob is deleted or moved before the tier's minimum period.
  • Lifecycle policies are executed once daily and may take up to 48 hours after creation for first execution.
  • Always include actions on snapshots and versions in lifecycle policies, not just on the base blob.
  • Storage Account default tier can only be Hot or Cool; never Cold or Archive.
  • Rehydration can be canceled by moving the blob back to Archive while still processing.