ACR reported storage much higher than sum of manifests (size mismatch)

Paolo Poto 0 Reputation points
2026-06-12T07:21:09.11+00:00

Hi,

I have an Azure Container Registry (Basic SKU, West Europe) where the reported used storage stays around 31.3 GiB even after deleting old images and reducing the number of manifests per repository.

The registry currently has only three repositories (let's call them repo-1, repo-2, repo-3). For each repository I now keep only 2

manifests.

Using the Azure CLI:

az acr manifest list-metadata \

  --registry <registry-name> \

  --name <repo> \

  --query "[].{Digest:digest, Size:imageSize}" \

  -o table

I see approximate sizes like:

  • repo-1: each manifest ≈ 360 MB
  • repo-2: each manifest ≈ 360 MB
  • repo-3: each manifest ≈ 80 MB

So one "release" of these three images is roughly 360 + 360 + 80 ≈ 800 MB. With 2 manifests per repository I would

expect on the order of ~1.6 GB total (even considering an earlier state with a few more manifests, still just a few GB), not 31.3 GiB of used storage.

Soft delete is disabled, and the retention policy for untagged manifests is also disabled.

My questions are:

  1. Is there anything else in ACR (such as orphaned layers, hidden artifacts, or delayed background cleanup) that could explain this difference between reported storage and the sum of manifest sizes?
  2. Is there a way (CLI, API, or portal) to get a more detailed breakdown of what exactly is consuming storage in the registry?
  3. Under which conditions does ACR recalculate or update the used storage metric, and could it be temporarily out of sync?

Any guidance or pointers to documentation about how ACR computes the Used storage metric and how to troubleshoot such discrepancies would be appreciated.

Thanks!

Paolo

Azure Container Registry
Azure Container Registry

An Azure service that provides a registry of Docker and Open Container Initiative images.


2 answers

Sort by: Most helpful
  1. Anonymous
    2026-06-12T07:55:30.3433333+00:00

    Hi Paolo,

    Thanks for the detailed numbers this really helps.

    The behavior you are seeing is expected by design for Azure Container Registry, and the gap between az acr show-usage (~31.7 GiB) and the sum of imageSize from az acr manifest list-metadata (~1.49 GiB) does not by itself indicate a billing or platform bug. Let me address your three questions directly.

    1. Why the reported Used storage is higher than the sum of manifest sizes

    az acr show-usage reports total backend blob storage consumed by the registry (shared layers + manifest files + replica copies), not the sum of manifest imageSize values.

    Common reasons for a large delta: [learn.microsoft.com]

    • Shared / orphaned layers – Layers referenced by multiple manifests are stored only once and are reclaimed only when the last referencing manifest is deleted. Deleting one image only frees layers that are unique to it, so storage often drops by less than expected. [learn.microsoft.com]
    • Untagged ("dangling") manifests from repeated pushes with the same tag – Each re-push with the same tag untags the previous manifest. Those untagged manifests (and their unique layers) keep consuming storage until they are explicitly deleted, even though they do not appear in repository show-tags. [danielstechblog.io], [medium.com]
    • Asynchronous garbage collection – After a manifest is deleted, the underlying blobs are reclaimed by the platform asynchronously. The Used value can lag the actual cleanup. [learn.microsoft.com]
    • Non-image artifacts – Helm charts, OCI artifacts, cache/import artifacts, and signatures also count toward registry storage.

    So even with only 6 tagged manifests visible today, the registry can still be holding untagged manifests / unreferenced layers from earlier pushes that account for the ~30 GiB delta.

    1. Getting a more detailed breakdown - ACR intentionally does not expose a per-repository or per-layer storage breakdown – this is a long-standing, by-design limitation tracked in the public ACR repo.

    The supported options today are:

    • Registry-level – az acr show-usage -n <registry> (snapshot, may lag) and the StorageUsed platform metric in Azure Monitor (1-hour grain, average, geo-dimension). For fresher data than the portal "Used storage" tile, query StorageUsed directly via Monitor Metrics.
    • Manifest-level – az acr manifest list-metadata to list manifests, including untagged ones. Filter untagged with --query "[?tags[0]==null]". [learn.microsoft.com]
    1. Recommended cleanup steps

    a) Enumerate untagged manifests per repository:

    az acr manifest list-metadata -r <registry> -n <repo> \
      --query "[?tags[0]==null].digest" -o tsv
    

    b) Delete untagged manifests (after review):

    az acr manifest list-metadata -r <registry> -n <repo> \
      --query "[?tags[0]==null].digest" -o tsv \
      | xargs -I% az acr repository delete -n <registry> -t <repo>@% --yes
    

    c) Or do a dry-run via acr purge first, then run for real:

    az acr run --cmd \
      "acr purge --filter '<repo>:.*' --untagged --ago 0d --dry-run" \
      --registry <registry> /dev/null
    

    d) Validate reclamation – After deletion, allow a few minutes for asynchronous garbage collection, then re-check az acr show-usage and the StorageUsed metric in Azure Monitor (this is the documented validation pattern). [learn.microsoft.com]

    Was this answer helpful?


  2. AI answer

    2026-06-12T07:21:26.38+00:00
    1. Yes, there are additional factors that can explain a mismatch between the sum of manifest sizes and the reported Used storage:
      • Shared layers across manifests: ACR stores layers only once even if multiple manifests reference them. Deleting a manifest only frees the layers that are no longer referenced by any other manifest. If older or other images still reference those layers, storage usage will not drop as much as expected. This behavior is described for delete operations where “layers that are referenced by multiple different manifests are stored only one time,” and deleting one image only removes layers that are unique to that image.
      • Untagged/orphaned manifests: Repeatedly pushing modified artifacts with the same tags can create untagged artifacts whose layers still occupy space. These untagged images do not appear when listing by tag, but their layers remain until the last referencing manifest is deleted. Deleting such untagged images frees space only when their layers are not shared with other manifests.
      • Non‑image artifacts and many repositories/tags: ACR storage includes all repositories, images, layers, tags, and artifacts up to the registry storage limit. High numbers of repositories and tags can increase storage and affect performance, even if only a small subset is actively used.
    2. For a more detailed breakdown of storage consumption, ACR exposes only coarse-grained usage information:
      • Use az acr show-usage -n <registry> to get a snapshot of storage consumed in bytes and other usage metrics for the registry’s SKU. This shows total storage but not per-repository or per-layer breakdown.
      • At the repository level, az acr manifest list-metadata can be used to list manifests and their sizes, and you can script deletions of untagged manifests (for example, by querying for manifests where tags[0]==null and deleting them). However, ACR does not expose a built-in per-layer or per-repository storage accounting API beyond manifest sizes.
      There is no documented CLI, API, or portal view that breaks down Used storage by repository or by layer; troubleshooting is typically done by listing manifests, identifying untagged/orphaned ones, and deleting them.
    3. ACR storage usage updates and temporary discrepancies:
      • Storage usage is tied to the underlying blobs (layers) referenced by manifests. When images with no shared layers are deleted, the registry usage should update within a few minutes.
      • The portal’s Used storage value and az acr show-usage provide a snapshot and might not reflect all recent operations immediately. Documentation notes that registry storage usage might lag and recommends monitoring the StorageUsed metric for more up-to-date data.
      • In scenarios where images share layers, deleting some manifests will not reduce storage as much as expected because shared layers remain until all referencing manifests are deleted.

    To troubleshoot discrepancies:

    • List manifests per repository and identify untagged ones (orphans) using az acr manifest list-metadata and delete them if they are no longer needed.
    • After deleting images that are known not to share layers (for example, by creating a test image with a unique 1 GB layer, pushing it, then deleting it), verify that storage usage changes using az acr show-usage and the portal. This pattern is documented as a way to validate storage quota changes.

    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.