Unattached EBS volumes, unattached managed disks and persistent disks without users are block storage left behind when their instance was deleted and billed by size and month ever since, written to or not. The saving comes from a volume without an instance having no purpose a snapshot does not serve more cheaply: back up, delete, and the line leaves the bill. The fix belongs to the team that deleted the instance, with a deadline after which the cloud owner works through the list.

Symptom

The bill carries volumes with no instance line to match. On AWS these are lines with lineItem/UsageType EUC1-EBS:VolumeUsage.gp3 or EUC1-EBS:VolumeUsage.gp2 and lineItem/ProductCode AmazonEC2, whose lineItem/ResourceId is a vol- id with no BoxUsage of the same instance beside it. On Azure they appear under MeterCategory Storage with MeterSubCategory Premium SSD Managed Disks or Standard SSD Managed Disks and a MeterName such as P10 LRS Disk, the ResourceId ending in disks/<name>. On Google Cloud it is the SKU Storage PD Capacity or Balanced PD Capacity under Compute Engine per resource.name. What a volume costs is in block, object and file storage; what separates idle from orphaned is in idle and orphaned resources.

yes: BoxUsage of thesame instancenoA volume line keepscounting: EBS VolumeUsage,Managed Disks, StoragePD CapacityAn instance linebeside it?Not this page: a volumeof a running instanceUnattached: the volumebills with no instanceto match
An unattached volume is a storage line with no instance line of the same resource beside it

How to detect it

AWS

A volume without an instance is in the available state. The list with size, type and age:

aws ec2 describe-volumes --filters Name=status,Values=available \
  --query 'Volumes[].[VolumeId,Size,VolumeType,CreateTime,Tags[?Key==`Name`].Value|[0]]' --output table

CreateTime is the volume's age, not the time it was detached; CloudTrail gives that with aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DetachVolume for the last 90 days. Two checks AWS runs (read on 2026-10-21): Trusted Advisor flags under "Underutilized Amazon EBS volumes" a volume that is unattached or had less than 1 IOPS per day for the past seven days; Compute Optimizer classifies a volume as Unattached when it was attached to no instance over 32 days, and as Idle when read and write operations over the lookback period stayed below one per day and it is not a root volume; the recommended action in both cases is a snapshot and a deletion:

aws compute-optimizer get-idle-recommendations --filters name=ResourceType,values=EBSVolume

In billing data the candidate is a vol- resource with EBS:VolumeUsage whose instance carries no BoxUsage in the same month (AWS Cost and Usage Report).

Azure

A managed disk without a VM has the diskState Unattached:

az disk list --query "[?diskState=='Unattached'].{name:name, gb:diskSizeGb, sku:sku.name, rg:resourceGroup, created:timeCreated}" -o table

timeCreated is again the disk's age; the time of the detachment is in the resource group's activity log. Azure Advisor carries, in preview, the recommendation "Review disks that aren't attached to a VM and evaluate if you still need the disks", which excludes the replica disks of Azure Site Recovery and asks for a snapshot before the deletion:

az advisor recommendation list --category Cost --query "[?contains(shortDescription.problem, 'disks')].{resource:resourceMetadata.resourceId, problem:shortDescription.problem}" -o table

In the cost export the candidate is a ResourceId on disks/ with a disk meter and no Virtual Machines row for its VM; the disk does not inherit the VM's tags, so only the resource group helps (Azure cost exports).

Google Cloud

A persistent disk without users has an empty users field, and lastDetachTimestamp names the time of the detachment:

gcloud compute disks list --filter="-users:*" \
  --format="table(name,zone.basename(),sizeGb,type.basename(),lastDetachTimestamp,creationTimestamp)"

The idle persistent disk recommender, google.compute.disk.IdleResourceRecommender, returns the same list with a cost estimate per zone (Recommenders):

gcloud recommender recommendations list --project=<project-id> --location=<zone> \
  --recommender=google.compute.disk.IdleResourceRecommender --format="table(name.basename(),description,stateInfo.state)"

In the billing export the candidate carries Storage PD Capacity or Balanced PD Capacity on a resource.name with no Instance Core running line (Google Cloud billing export).

How to fix it

  1. Sort the list by age and agree it with the owner from the tag or resource group; a deadline from the cost policy, say 30 days without an instance, decides when a volume goes on the deletion list.
  2. Back up, then delete. AWS: aws ec2 create-snapshot --volume-id vol-0123456789abcdef0 --description "orphan 2026-10-21" --dry-run, then aws ec2 delete-volume --volume-id vol-0123456789abcdef0 --dry-run; both without --dry-run only after the release. Azure: az snapshot create --resource-group <rg> --name <snapshot> --source <disk> --incremental true, then az disk delete --resource-group <rg> --name <disk>, without a dry run, so only against the checked list. Google Cloud: gcloud compute disks snapshot <disk> --zone=<zone> --snapshot-names=<snapshot>, then gcloud compute disks delete <disk> --zone=<zone>.
  3. Remove the cause: on AWS DeleteOnTermination in the launch template's block device mapping for data volumes that belong to the instance; on Azure the delete option for OS and data disks in the VM definition; on Google Cloud --auto-delete on the disk attachment. A volume meant to outlive its instance gets a tag with its purpose and owner instead.
  4. The snapshots from step 2 get an expiry date, or the line merely moves into old snapshots and machine images.

The line ends with the deletion; the next daily export no longer shows it.

no, or meant tooutlive its instanceyesSort by age, agree with theowner from the tag orresource groupLonger without aninstance than thecost policy allows?Stays, with a tag namingpurpose and ownerSnapshot first,the reversible stepDelete the volume,after the releaseRemove the cause: deletewith the instance setin the templateThe snapshots get an expirydate, or the line moves toold snapshots and images
The deadline sorts the list, the snapshot comes before the delete, and the template and the snapshot expiry keep the line from returning

Risks and side effects

  • A volume without an instance is sometimes deliberate: a data disk detached between batch runs, a prepared volume for a failover, a dataset waiting for a handover. The tag or name says so, the question to the owner decides.
  • Deletion is final at all three providers; the snapshot from step 2 is the only way back, and a restore should have been rehearsed once.
  • A snapshot is not free: it is billed by stored data, on Azure incrementally on standard HDD storage, on AWS incrementally per volume. For a volume that is empty anyway it is not worth it; for one with data it is cheaper than the volume for the policy's holding period.
  • Azure Site Recovery and backup services hold replica disks without a VM that belong to the configuration; Advisor excludes them, and a list of your own has to as well.
  • On Azure a reserved disk SKU, a reservation for P30 for instance, stays unused after the deletion until another disk fills it (commitment coverage and utilisation).

How to verify the saving

Before: per volume id, the amount of the EBS:VolumeUsage, disk meter or PD Capacity line in the last full month, summed over the deletion list. After: the same ids in the first full month after the deletion, expected zero, and beside them the new snapshot lines, EBS:SnapshotUsage, the Snapshots meters and the Storage Snapshot SKUs, which the proof nets off. The sum of the deletion list is the estimate, the team's consent makes it accepted, the deletion implemented, and the following month's invoice realises it in the pattern of estimated, accepted, implemented, verified. The number of volumes without an instance older than the deadline is the figure that has to stay at zero afterwards.

Sources

Read on 2026-10-21. Trusted Advisor cost optimization checks, Compute Optimizer idle resource recommendations, describe-volumes, Azure Advisor cost recommendations, az disk, Recommenders, gcloud compute disks list.