Start with Cloud Advisor
Cloud Advisor's cost management recommendations list idle compute, unattached volumes, idle load balancers and other items with estimated savings. Use it as the first list, then dig deeper with Search.
1. Detached block volumes
# all volumes in AVAILABLE state
oci search resource structured-search --query-text \
"query volume resources where lifecycleState = 'AVAILABLE'" \
--query 'data.items[].{name:"display-name",id:identifier,c:"compartment-id"}' --output table
A volume in AVAILABLE may or may not be attached. Check attachments:
oci compute volume-attachment list --compartment-id $C --volume-id $VOL --query 'data[?"lifecycle-state"==`ATTACHED`]'
No attachment → candidate. Enable detached-volume auto-tune meanwhile to cut its cost (see the VPU post).
2. Boot volumes left after termination
Instances terminated with "preserve boot volume" leave boot volumes that keep billing:
oci search resource structured-search --query-text "query bootvolume resources where lifecycleState = 'AVAILABLE'" \
--query 'data.items[].{name:"display-name",id:identifier,created:"time-created"}' --output table
oci compute boot-volume-attachment list --availability-domain "$AD" --compartment-id $C --boot-volume-id $BOOT
3. Stopped instances
oci search resource structured-search --query-text "query instance resources where lifecycleState = 'STOPPED'" \
--query 'data.items[].{name:"display-name",id:identifier,c:"compartment-id"}' --output table
For most VM shapes, stopped instances don't bill compute but their boot and block volumes still bill. Some shapes (e.g. dense I/O, GPU or bare metal, depending on current rules) can continue to bill when stopped. Instances stopped for months are usually candidates for a final backup and termination.
4. Old manual backups
oci bv backup list --compartment-id $C --query \
'data[?"source-type"==`MANUAL`].{name:"display-name",created:"time-created",gb:"unique-size-in-gbs"}' --output table
oci bv boot-volume-backup list --compartment-id $C --query \
'data[?"source-type"==`MANUAL`].{name:"display-name",created:"time-created"}' --output table
Manual backups don't expire unless you set an expiry. Agree a retention with owners and delete the rest.
5. Idle load balancers
Load balancers with near-zero BytesReceived over 30–90 days (see the load balancer post). Check DNS records first.
6. Databases nobody uses
- Autonomous Databases with no sessions for weeks: stop them, then ask owners.
- DB systems for finished projects.
- Old database backups in Object Storage from on-prem RMAN migrations.
7. Other common leftovers
| Resource | Check |
|---|---|
| Reserved public IPs not assigned | oci network public-ip list --scope REGION --lifetime RESERVED --compartment-id $C |
| Custom images from old builds | Keep current and previous; delete older ones not referenced by instance configs |
| Object Storage buckets from tests | Size and last-modified; lifecycle rules |
| OKE leftovers | LBs and volumes from deleted clusters |
| File systems and mount targets | No clients mounted (metrics), owner confirmation |
Clean up safely
- Tag candidates (
cleanup-candidate=2026-11-15) and notify owners (fromCreatedBydefined tags if you use them). - Wait the notice period.
- Back up if there's any doubt (volume backup with expiry, database export).
- Delete, and record what was removed.
Keep it from coming back
- Required
ownerandenvironmenttags (tag defaults and IAM conditions). - Monthly Cloud Advisor review per compartment owner.
- Budgets per compartment with alerts.
- Automation (Functions + Events) that flags volumes detached for more than N days.
Caution
Terminated instances and deleted volumes can't be recovered unless you kept a backup. Tag, notify, back up, then delete. Never in the reverse order.
Checklist
- Cloud Advisor cost recommendations reviewed
- Detached volumes and preserved boot volumes listed
- Long-stopped instances reviewed
- Manual backups given retention
- Idle LBs, unused databases, IPs, images, buckets checked
- Tag → notify → backup → delete process followed