AWSCost

AWS cost · ECR

Unused ECR images: what deleting them really frees

Every CI pipeline that builds containers leaves years of images behind it, and clearing them out is the obvious win. The trouble is working out what the cleanup is worth. The number most tools reach for - the sum of the image sizes - is wrong by five to ten times, always in the direction that makes the saving look bigger.

ECR bills $0.10/GB-month for layers, and stores each layer once per repository however many images use it. So deleting an image frees only the layers nothing else references. Fifty builds sharing a 500 MB base layer report about 25 GB between them; AWS is charging for roughly 1.5 GB.

What ECR charges, and what a cleanup returns

WhatCostNote
Stored layers$0.10/GB-monthus-east-1, counted once per repository
200 GB of layers in a repository~$20.00/monthwhat AWS actually bills
The same repository, image sizes summed5-10x highera number no bill will ever show
Deleting an image whose layers survive elsewhere$0.00 freedshared layers stay, and stay billed

Why the obvious number is wrong

A container image is a stack of layers plus a small config blob. Rebuild an application on the same base image and the new build shares every layer below your own code. That is the point of the format, and the reason a push takes seconds.

The API reports each image at the size of all its layers anyway, because that is what the image weighs when you pull it. Add those figures up across a repository and you have counted the base layer once per build. AWS counted it once in total.

For a multi-architecture image the same field under-reports instead: it gives the largest child, not the total. It is wrong in both directions.

The number that is actually true

Deleting a set of images frees the layers no surviving image references, plus each deleted config blob, which is never shared. Everything else stays where it is and stays on the bill.

Getting that number means fetching each manifest and comparing layer digests between what you are deleting and what you are keeping. More work than summing a column, and the difference between a saving you can promise and one you have to apologise for.

How to find images nobody pulls

ECR records the last time each image was pulled and hands it back on the describe call, so this costs nothing to check:

# repositories in this region
aws ecr describe-repositories --query 'repositories[].repositoryName' --output text

# push and last-pull times per image, oldest push first
aws ecr describe-images --repository-name my-app \
  --query 'sort_by(imageDetails,&imagePushedAt)[].{Digest:imageDigest,Pushed:imagePushedAt,LastPull:lastRecordedPullTime,Bytes:imageSizeInBytes}' \
  --output table

# the manifest, where the real layer digests and sizes live
aws ecr batch-get-image --repository-name my-app \
  --image-ids imageDigest=sha256:abc123... \
  --query 'images[].imageManifest' --output text

Judge an image on the later of its push and pull times. A rebuilt image can be pushed today and never pulled since, and reading the pull time alone would call it dead. An image with neither timestamp is not evidence of disuse - treat it as unknown.

What the cleanup costs

Rollbacks stop at the oldest image you kept. The images that look most deletable - the ones nobody has pulled in a year - are exactly the ones a rollback reaches for in the worst hour of an incident.

Anything pinned by digest breaks outright. A digest names exact bytes, so a rebuild gets a new one and the old reference can never be satisfied. Check pinned deployment manifests and container-image Lambda functions first.

# MUTATING - deletion is permanent, a digest cannot be recreated
aws ecr batch-delete-image --repository-name my-app \
  --image-ids imageDigest=sha256:abc123...

Deleting by hand fixes today and not next year. The durable answer is a lifecycle policy that expires images on a rule, covered in ECR storage costs.

Want the honest number - the layers a cleanup would actually free? Connect your account read-only and see what it is wasting, in real dollars.

Connect your AWS

The role can only read - Get, Describe, List, nothing else. Read the exact permissions before you deploy it, and delete the stack whenever you want.

Frequently asked questions

How much does ECR storage cost?+

$0.10 per GB-month in us-east-1, charged on the layers stored in each repository. A layer is stored once per repository no matter how many images reference it, which is why the bill is almost always smaller than the sum of your image sizes.

Why does adding up image sizes overstate my ECR bill?+

Because imageSizeInBytes is the total of all of an image's layers, shared or not. Fifty CI builds on a common 500 MB base layer report about 25 GB between them, while ECR stores and charges for roughly 1.5 GB. Summing that field overstates storage by five to ten times.

How much will deleting old images actually save?+

Only the layers that no surviving image still references, plus each deleted image's own config blob, which is never shared. If every layer of an old image also appears in the current build, deleting it frees nothing at all - the tag disappears and the bill does not move.

Are untagged images safe to delete?+

Not automatically. A multi-architecture image is a manifest list whose per-platform children show up in the API as untagged images, so deleting everything untagged can break the tagged image that points at them. Untagged means unlabelled, not unused.

How do I tell whether an image is still being pulled?+

ECR records a last-pull time per image, and it comes back on the describe call - no metrics, no cost. Use the later of the pull time and the push time: an image re-pushed last week has not been pulled since, but it is clearly current. An image with neither timestamp is not evidence of anything.

What breaks when I delete old images?+

Rollbacks past the deleted images stop working, which matters most for exactly the old images that look most deletable. Anything referencing an image by digest - a pinned deployment manifest, a Lambda function on a container image - breaks immediately, because the digest cannot be recreated by rebuilding.

Related cost breakdowns

More AWS cost breakdowns