Blob Versioning in Azure Storage

Azure Blob versioning automatically saves a copy of a blob every time it is overwritten or deleted. This gives you a safety net against accidental changes — you can restore any previous version of a blob without needing a separate backup system. The catch is cost: every version is stored and billed individually.

How versioning works

When you enable versioning on a storage account, Azure starts tracking every state of every blob. The current blob is called the current version. Every time you overwrite or replace a blob, the old content becomes a previous version, identified by a version ID that looks like a timestamp: 2026-03-19T12:34:56.1234567Z.

When you delete a blob with versioning enabled, the blob is not truly gone. The current version is removed from the namespace (so listing the container won’t show it), but previous versions remain accessible by version ID until you delete them explicitly.

This behavior is different from soft delete. Soft delete puts a deleted blob into a hidden state and automatically removes it after a retention period. Versioning preserves every previous state indefinitely until you explicitly delete the versions or use a lifecycle policy to clean them up.

Enabling versioning

Versioning is disabled by default. You enable it at the storage account level, and it applies to all containers in that account.

# Enable blob versioning on a storage account
az storage account blob-service-properties update \
  --account-name mystorageaccount123 \
  --resource-group my-storage-rg \
  --enable-versioning true

# Confirm it's enabled
az storage account blob-service-properties show \
  --account-name mystorageaccount123 \
  --resource-group my-storage-rg \
  --query "isVersioningEnabled"

Enabling versioning only affects blobs going forward. Blobs that existed before you enabled versioning do not get retroactive version history — they become “current versions” with no prior versions.

Viewing and working with versions

# Upload an initial blob
az storage blob upload \
  --account-name mystorageaccount123 \
  --container-name documents \
  --name report.pdf \
  --file ./report-v1.pdf \
  --auth-mode login

# Overwrite it with a new version
az storage blob upload \
  --account-name mystorageaccount123 \
  --container-name documents \
  --name report.pdf \
  --file ./report-v2.pdf \
  --auth-mode login

# List all versions of the blob
az storage blob list \
  --account-name mystorageaccount123 \
  --container-name documents \
  --include v \
  --auth-mode login \
  --query "[?name=='report.pdf']" \
  --output table

The —include v flag tells the list command to include versions in the output. Each version has a versionId property you’ll use to access or restore a specific version.

# Download a specific previous version by version ID
az storage blob download \
  --account-name mystorageaccount123 \
  --container-name documents \
  --name report.pdf \
  --version-id "2026-03-19T10:00:00.0000000Z" \
  --file ./report-recovered.pdf \
  --auth-mode login

Restoring a previous version

To restore a previous version as the current version, copy the old version over the current blob:

# Get the version ID you want to restore (from the list command above)
VERSION_ID="2026-03-19T10:00:00.0000000Z"
ACCOUNT="mystorageaccount123"
CONTAINER="documents"
BLOB="report.pdf"

# Copy the old version to become the new current version
az storage blob copy start \
  --account-name $ACCOUNT \
  --destination-container $CONTAINER \
  --destination-blob $BLOB \
  --source-uri "https://$ACCOUNT.blob.core.windows.net/$CONTAINER/$BLOB?versionId=$VERSION_ID" \
  --auth-mode login

This creates a new current version with the content of the old version. The original current version becomes a previous version (not deleted). You now have both the restored state and the overwritten state in your version history.

Deleting versions to control cost

Without cleanup, versions accumulate indefinitely. A frequently updated blob in a high-traffic system can generate thousands of versions per day. Use lifecycle policies to automatically delete old versions:

{
  "rules": [
    {
      "name": "CleanupVersions",
      "enabled": true,
      "type": "Lifecycle",
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"]
        },
        "actions": {
          "version": {
            "delete": {
              "daysAfterCreationGreaterThan": 30
            }
          }
        }
      }
    }
  ]
}

This keeps previous versions for 30 days, then deletes them. The current version is never touched by the version cleanup action.

To delete a specific version manually:

az storage blob delete \
  --account-name mystorageaccount123 \
  --container-name documents \
  --name report.pdf \
  --version-id "2026-03-19T08:00:00.0000000Z" \
  --auth-mode login

Versioning and soft delete together

Soft delete and versioning are separate but complementary features. Microsoft recommends enabling both:

  • Versioning protects against overwrites — you can go back to any previous state of a blob.
  • Soft delete protects against container-level or accidental version deletion — deleted versions go into a recoverable state for the retention period.
# Enable soft delete for blobs with 14-day retention
az storage account blob-service-properties update \
  --account-name mystorageaccount123 \
  --resource-group my-storage-rg \
  --enable-delete-retention true \
  --delete-retention-days 14

# Enable soft delete for containers
az storage account blob-service-properties update \
  --account-name mystorageaccount123 \
  --resource-group my-storage-rg \
  --enable-container-delete-retention true \
  --container-delete-retention-days 14
Note

When both versioning and soft delete are enabled, Azure behavior changes slightly: deleting a blob with no versions creates a soft-deleted blob. Deleting a blob that has versions does not create a soft-deleted marker — the current version is simply removed, and previous versions are accessible as usual. The details matter when you’re building recovery procedures.

Common mistakes

  1. Enabling versioning on high-churn blobs without a cleanup policy. Application log blobs that get appended to every minute will accumulate thousands of versions. Without a lifecycle rule to delete old versions, your storage costs will grow much faster than expected. Always pair versioning with a version cleanup policy.
  2. Assuming versioning protects against container deletion. Deleting a container removes everything inside it — all blobs and all their versions. Versioning only helps at the blob level. Use Azure resource locks or backup vaults for container-level protection.
  3. Restoring by overwriting the current blob without understanding the version chain. Overwriting the current blob during a restore creates a new current version and demotes the previous current to a previous version. The chain keeps growing. If you wanted the “bad” version gone, you need to explicitly delete the version you don’t want after restoring.
  4. Forgetting that versioning doesn’t help if you never set it up before the incident. Versioning only protects blobs from the moment it was enabled. If an accidental deletion happens the day before you enable versioning, there’s nothing to recover. Enable data protection features proactively, not reactively.

Frequently asked questions

What is the difference between blob versioning and snapshots?

Versioning is automatic — Azure creates a new version every time a blob is modified or overwritten. Snapshots are manual — you explicitly call a snapshot operation to capture a point-in-time copy. Versioning is generally preferred for automation; snapshots are useful when you want a deliberate checkpoint before a known change.

Does versioning protect against container deletion?

No. If a container is deleted, all blobs and their versions inside it are permanently deleted. Versioning protects against blob-level overwrites and deletes. To protect against container deletion, use resource locks or backup policies.

How much does versioning cost?

Each version is billed as a separate blob for storage. If a 100 MB blob has 10 versions, you are billed for 1,000 MB of storage. The versions share blocks if data is unchanged, so the actual storage cost depends on how much content changed between versions — but you should expect significantly higher storage bills with versioning enabled on large, frequently changing blobs.

Last verified: 19 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.