---
title: "Delete resources that sit idle · Agent Wranglers"
url: https://agentwranglers.se/playbook/infrastructure/cost-and-ownership/delete-idle-resources
updated: 2026-10-20
licence: "All rights reserved"
---

# Delete resources that sit idle

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Recommended
- Chapter: [Cost and ownership](https://agentwranglers.se/playbook/infrastructure/cost-and-ownership)
- Rule: Run a weekly job that lists idle resources and deletes them after their owner has had 7 days to object.
- How: List disks attached to nothing, unused public addresses and load balancers with no targets. Add snapshots older than 90 days and servers stopped for 14 days. Tell the owner from the tags. Stop development servers at night and on weekends. Set lifecycle rules on buckets, so old files move to cheaper storage or expire.
- Check: The weekly report lists no resource that was already on last week's report and had no objection.

Example:

```python
import boto3

ec2 = boto3.client("ec2")
volumes = ec2.describe_volumes(Filters=[{"Name": "status", "Values": ["available"]}])["Volumes"]
for volume in volumes:
    owner = next((t["Value"] for t in volume.get("Tags", []) if t["Key"] == "owner"), "no owner")
    print(volume["VolumeId"], volume["Size"], "GiB", owner)
addresses = [a["PublicIp"] for a in ec2.describe_addresses()["Addresses"] if "AssociationId" not in a]
print("Unused addresses:", addresses)
```

```js
import { EC2Client, DescribeVolumesCommand, DescribeAddressesCommand } from '@aws-sdk/client-ec2';

const ec2 = new EC2Client({});
const { Volumes } = await ec2.send(new DescribeVolumesCommand({ Filters: [{ Name: 'status', Values: ['available'] }] }));
for (const volume of Volumes) {
  const owner = volume.Tags?.find(tag => tag.Key === 'owner')?.Value ?? 'no owner';
  console.log(volume.VolumeId, volume.Size, 'GiB', owner);
}
const { Addresses } = await ec2.send(new DescribeAddressesCommand({}));
console.log('Unused addresses:', Addresses.filter(address => !address.AssociationId).map(address => address.PublicIp));
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers infrastructure playbook: https://agentwranglers.se/playbook/infrastructure/cost-and-ownership/delete-idle-resources`.

- Previous: [Give every account a budget with alerts](https://agentwranglers.se/playbook/infrastructure/cost-and-ownership/budgets-for-every-account)
- Next: [Size servers from what they use](https://agentwranglers.se/playbook/infrastructure/cost-and-ownership/rightsize-from-measurements)
- [Cost and ownership](https://agentwranglers.se/playbook/infrastructure/cost-and-ownership)
