Skip to main content
orphan · aws

ECR images not pulled in 90 days, priced as a share of the repository bill

resource types
1
rule IDs covered
1
severity
low

What does ZopNight detect here?

ZopNight flags ECR repositories holding images whose `lastRecordedPullTime`, or push time if never pulled, is more than 90 days old. The saving is up to the repository's measured cost multiplied by the stale images' share of total bytes, capped at the full cost, and it skips repositories already governed by a `sinceImagePulled` lifecycle rule.

Signal and threshold

How ZopNight evaluates ECR images not pulled in 90 days, priced as a share of the repository bill.
Field Value
Rule IDsRC-022
Categoryorphan
Severitylow
Metricnone — pure configuration read
Thresholdlast pull (or push) older than 90 days
Evaluation window90d
SourceZopNight
Permissions usedecr:DescribeRepositories · ecr:DescribeImages · ecr:GetLifecyclePolicy

Old images pay the same storage rate as live ones

Every image pushed to ECR stays in private repository storage until something deletes it. CI pipelines push a new image per build, so a busy repository can hold thousands of images of which a handful are ever pulled again. Tag status is a poor guide: an untagged image may be the live child of a multi-architecture index, while a tagged release from two years ago may never be pulled again.

Listing images by last pull

describe-images returns lastRecordedPullTime, which the ImageDetail reference says ECR refreshes at least once every 24 hours:

Terminal window
aws ecr describe-images --repository-name my-repo \
--query 'imageDetails[].[imageDigest,imageTags[0],imagePushedAt,lastRecordedPullTime,imageSizeInBytes]' \
--output table

Images whose last pull, or push if there is no pull, is more than 90 days old are candidates. Read the metadata only. Calling batch-get-image to inspect manifests is recorded as a pull and resets lastRecordedPullTime, a behaviour tracked in the public containers roadmap.

How the reclaimable share is built

ZopNight adds up the size of every image not pulled in over 90 days, counting a never-pulled image only once it was pushed more than 90 days ago. Two safety filters apply. An image index is never offered, because deleting one frees only the manifest while AWS reports its size as the largest manifest in the list. In a repository that contains an index, untagged images are not offered, since they may belong to a live parent. The result is always an upper bound: layers shared between images are counted once per image.

When the check holds back

If the repository has a lifecycle rule using sinceImagePulled, ECR is already scheduled to expire these images, so there is no finding. A policy that expires only by push age does not count. If the whole repository shows zero pulls for 90 days, ECR Repository Never Pulled takes it instead. No finding is raised when the stale bytes, the repository’s total size or its cost are unknown.

Pricing the stale share

Terminal window
saving = repository monthly cost x (stale image bytes / total repository bytes), capped at 1
cost after fix = repository cost - saving

Using the repository’s own measured spend keeps the figure right under private pricing and in any Region, and every figure is shown as “up to”.

Pruning images by pull age

  1. Review the listed images and keep anything held for rollback or disaster recovery.
  2. Delete the rest by digest: aws ecr batch-delete-image --repository-name my-repo --image-ids imageDigest=sha256:....
  3. Add a lifecycle rule with the sinceImagePulled count type so ECR expires cold images on its own; the lifecycle policy parameters list it alongside sinceImagePushed.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

472 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

472 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·