Back to blog
AWSBest PracticesCloud SecurityCost OptimizationStorage

EBS Snapshots Older Than 1 Year: Find, Fix, and Prevent

Forgotten EBS snapshots quietly cost money and expose data. Learn how to find snapshots older than a year, safely delete or archive them, and automate cleanup.

TL;DR

This check flags EBS snapshots older than 365 days, which usually means forgotten backups quietly accruing storage charges. Audit them, confirm none are tied to active AMIs or compliance retention, and delete or archive the ones you no longer need.

Every team accumulates EBS snapshots. You take one before a risky migration, another as a quick safety net before patching, and a few more get created automatically by backup jobs that nobody owns anymore. A year later, those snapshots are still sitting in your account, costing money and adding noise to every audit you run.

The EBS Snapshot Older Than 1 Year check exists to surface exactly these forgotten artifacts so you can decide, deliberately, whether each one still earns its keep.


What this check detects

Lensix flags any EBS snapshot whose creation timestamp is more than 365 days in the past. The logic is simple: it reads the StartTime attribute on each snapshot in a region and compares it against the current date.

A flagged snapshot is not automatically a problem. It is a candidate for review. Some snapshots are old because they back an AMI you still depend on, or because a compliance policy requires you to keep them for seven years. The check does not assume intent, it just makes the age visible so a human can make the call.

Note: EBS snapshots are incremental. The first snapshot of a volume captures every used block, and each subsequent snapshot only stores the blocks that changed since the last one. This means deleting one old snapshot does not always free as much space as you would expect, because the data it references may still be needed by newer snapshots in the chain.


Why it matters

Storage cost

EBS snapshots are billed per GB-month of stored data in S3-backed snapshot storage. The standard rate is roughly $0.05 per GB per month in most regions. A single 500 GB snapshot left untouched for a year costs around $300, and large accounts routinely hold thousands of orphaned snapshots. This is the kind of spend that never shows up in a cost review because it is spread thinly across hundreds of tiny line items.

Audit and compliance noise

Old snapshots clutter your inventory. When an auditor asks you to account for every piece of stored customer data, a pile of year-old snapshots with no clear owner forces you to investigate each one. Snapshots can contain sensitive data lifted straight off a production volume, including database files, secrets written to disk, and customer records. An unmanaged snapshot is unmanaged data.

Security exposure

This is the part teams underestimate. A snapshot can be shared with another AWS account or made public, and a forgotten snapshot is far more likely to have stale or overly broad sharing permissions that nobody is watching. If a snapshot of a sensitive volume was shared during a one-off task two years ago, that share is still live.

Warning: Snapshots created from encrypted volumes are themselves encrypted, but snapshots from unencrypted volumes are not. Old snapshots predate your current encryption standards more often than not, so an aging snapshot is frequently an unencrypted copy of data you have since locked down.


How to find and review the offending snapshots

Start by listing snapshots owned by your account, sorted so the oldest float to the top. The --owner-ids self filter is important, otherwise you will also pull in the thousands of public Amazon-owned snapshots.

aws ec2 describe-snapshots \
  --owner-ids self \
  --query 'Snapshots[?StartTime<=`2023-01-01`].[SnapshotId,StartTime,VolumeSize,Description]' \
  --output table

Adjust the date in the query to one year before today. Before deleting anything, check whether each snapshot is registered with an AMI. Deleting a snapshot that backs an AMI will break that image.

aws ec2 describe-images \
  --owners self \
  --query 'Images[].BlockDeviceMappings[].Ebs.SnapshotId' \
  --output text

Cross-reference the snapshot IDs from the first command against this list. Any snapshot that appears here is in use, leave it alone.

Also check sharing permissions on the old snapshots, since this is where exposure hides:

aws ec2 describe-snapshot-attribute \
  --snapshot-id snap-0123456789abcdef0 \
  --attribute createVolumePermission

If the output lists other account IDs or shows "Group": "all", that snapshot is shared more widely than it should be.


How to fix it

Option 1: Delete obsolete snapshots

Once you have confirmed a snapshot is not backing an AMI and is not under a retention requirement, delete it.

Danger: Snapshot deletion is irreversible. There is no recycle bin unless you have explicitly enabled Recycle Bin retention rules. Always confirm the snapshot is not referenced by an AMI and not needed for recovery or compliance before running the delete.

aws ec2 delete-snapshot --snapshot-id snap-0123456789abcdef0

To delete several at once after careful review, loop over a vetted list:

for snap in snap-0123456789abcdef0 snap-0fedcba9876543210; do
  echo "Deleting $snap"
  aws ec2 delete-snapshot --snapshot-id "$snap"
done

Option 2: Archive instead of delete

If you must keep a snapshot for compliance but rarely need to access it, move it to the EBS Snapshots Archive tier. Archived snapshots cost significantly less to store, with the tradeoff that restoring them takes 24 to 72 hours.

aws ec2 modify-snapshot-tier \
  --snapshot-id snap-0123456789abcdef0 \
  --storage-tier archive

Warning: Archiving has a minimum retention period of 90 days. If you archive a snapshot and delete it before 90 days pass, you still pay for the full 90 days of archive storage. Archive is for snapshots you genuinely intend to keep long-term, not for ones you are about to delete anyway.

Option 3: Enable Recycle Bin as a safety net

If you are nervous about bulk deletion, set up a Recycle Bin retention rule first. Deleted snapshots then enter a holding period during which you can recover them.

aws rbin create-rule \
  --resource-type EBS_SNAPSHOT \
  --retention-period RetentionPeriodValue=7,RetentionPeriodUnit=DAYS \
  --description "7-day recovery window for deleted EBS snapshots"

Tip: Set up the Recycle Bin rule before you start your cleanup campaign. It turns an irreversible delete into a reversible one for the duration of the retention window, which makes large cleanups far less stressful and gives you a buffer against deleting something you misjudged.


How to prevent it from happening again

Manual cleanup solves today's problem. Lifecycle automation solves it permanently.

Use Data Lifecycle Manager (DLM)

Amazon Data Lifecycle Manager creates and expires snapshots on a schedule based on tags. Define a policy once and it enforces retention automatically, which means snapshots no longer accumulate past their useful life.

{
  "ResourceTypes": ["VOLUME"],
  "TargetTags": [{ "Key": "Backup", "Value": "daily" }],
  "Schedules": [
    {
      "Name": "DailySnapshots",
      "CreateRule": { "Interval": 24, "IntervalUnit": "HOURS", "Times": ["03:00"] },
      "RetainRule": { "Count": 14 },
      "CopyTags": true
    }
  ]
}

Attach this to a DLM lifecycle policy and any volume tagged Backup=daily gets a fresh snapshot each morning, with only the most recent 14 retained. Nothing reaches a year old by accident.

Tag every snapshot with an owner and expiry

Snapshots without ownership tags are the ones that survive for years because nobody knows if they can be deleted. Enforce tagging at creation:

aws ec2 create-snapshot \
  --volume-id vol-0123456789abcdef0 \
  --description "Pre-migration backup" \
  --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Owner,Value=platform-team},{Key=ExpiresOn,Value=2025-06-01}]'

Gate it in IaC

If you manage snapshots through Terraform, you can fail a CI pipeline when a policy lacks a retention rule. A simple Open Policy Agent rule catches DLM policies that retain too many snapshots or none at all:

# Example: reject DLM policies that retain more than 30 snapshots
deny[msg] {
  policy := input.resource.aws_dlm_lifecycle_policy[name]
  policy.policy_details[_].schedule[_].retain_rule[_].count > 30
  msg := sprintf("DLM policy %v retains too many snapshots", [name])
}

Tip: Pair DLM with a continuous check in Lensix. DLM stops new snapshots from aging out of control, and the Lensix check catches the legacy snapshots created before your automation existed, plus anything created by hand outside your tagging conventions.


Best practices

  • Treat snapshots as data, not infrastructure. Each one is a copy of a disk that may hold secrets, PII, or credentials. Apply the same retention and access discipline you apply to the source volume.
  • Define retention by purpose. Daily operational backups rarely need to live past two weeks. Compliance snapshots may need years. Tag them differently so automation can treat them differently.
  • Audit sharing permissions regularly. Run a periodic sweep for snapshots shared with external accounts or marked public, and revoke anything that no longer needs the access.
  • Encrypt by default. Enable EBS encryption by default at the account level so every new snapshot is encrypted, closing the gap that old unencrypted snapshots represent.
  • Review the AMI dependency chain before deleting. Deregistering an AMI does not delete its backing snapshots, and deleting a backing snapshot breaks the AMI. Map the relationship before you act.
  • Make cleanup recurring, not one-off. A single cleanup feels great and then the backlog rebuilds. Schedule the review monthly or wire it into your continuous scanning so it never grows back.

Old snapshots are one of the cleanest wins in cloud cost and security hygiene. They cost real money, they widen your data exposure, and they almost always represent work nobody is doing on purpose. Find them, decide on each one with intent, and put automation in place so the same pile never forms again.