Azure Activity Log: The Missing Orphan Detection Signal
The Azure Activity Log records every control-plane write for 90 days, free. It answers the question metrics cannot: when was this resource last touched?
The Azure Activity Log is the subscription-level record of every control-plane write — every create, update, delete, role assignment, and configuration change — kept for 90 days at no charge. For orphan detection it is the strongest signal in the platform, and almost no cost tool reads it. That omission explains a pattern every long-time user of cost tooling recognizes: the same "maybe orphaned" resources appear on every monthly report, and nobody ever deletes them, because nobody is confident enough to act.
What does the Activity Log tell you that metrics cannot?
It answers the one question every other signal misses: when was this resource last touched by anyone? A VM that has been stopped for 30 days, with no metrics activity and no admin write in 90 days, is a high-confidence orphan. A VM stopped for 30 days that had a config change yesterday is almost certainly someone reactivating it manually. Same metadata, different story, and only the Activity Log can tell you which one you are looking at.
Metrics measure the data plane; the Activity Log records the control plane. A storage account can show zero transaction metrics simply because metrics were never enabled — the silence that causes the false positives dissected in why cost tools flag active resources. A 90-day control-plane history has no such blind spot: writes are recorded whether or not anyone configured telemetry.
Why do most cost tools skip it?
- Volume. A busy subscription generates hundreds of thousands of activity entries a month. They have to be aggregated and bucketed per resource, which is real pipeline work compared to reading resource metadata.
- Cardinality. Operation names and categories vary by service, so a generic "last touched" query has to handle dozens of patterns before it is useful.
- Incentives. Shipping a "stopped VM" check takes an afternoon; a 90-day rolling activity rollup takes an engineering quarter. Most tools ship the easy check and call it done.
What changes when you use it?
Pairing Activity Log with the signals you already have turns orphan detection from "here is a list to review" into "here is a list to act on":
- Stopped VM + no writes in 90 days + zero metrics — safe to delete, high confidence.
- Stopped VM + recent admin write — someone is still touching it; flag it, do not delete it.
- Unattached disk + never written since creation — almost certainly forgotten by whoever provisioned it.
- Storage account + no transactions + no role-assignment changes in 90 days — an audit-confident deletion candidate.
The point is not that the Activity Log replaces other signals. It is that it makes the confidence grade on each recommendation mean something. Without it you are guessing. With it you can tell an engineer "no one has touched this resource in 87 days" and get nodded through the change review. The usual suspects worth running this against are catalogued in how to find orphaned Azure resources.
How do you query it yourself?
For a single resource, the CLI gives you the recent history directly: az monitor activity-log list --resource-id <id> --offset 90d returns every logged operation in the retention window, and the newest entry's timestamp is your "last touched" date. In the portal, every resource has an Activity log blade with the same data. For estate-wide analysis, export the Activity Log to a Log Analytics workspace and query the AzureActivity table with KQL — summarize by resource ID, take the max timestamp, and join against your resource inventory. The export costs ingestion, so scope it to the subscriptions you actually analyze; the tuning levers in Azure Monitor cost tuning apply here too.
The limitation to respect: 90 days is the free retention ceiling, so "never touched" really means "not touched in 90 days." For most cleanup decisions that is exactly the window that matters. If you need a longer horizon, exporting to a workspace starts the clock on your own retention — begin the export before you need the history, not after.
How does CloudRift use it?
CloudRift pulls 90 days of Activity Log alongside every scan and computes a per-resource "last touched" date and recent write count. The signal flows straight into each finding's confidence grade, and every recommendation cites it explicitly: hover on "Confidence: Very High" and you read "Last touched 87 days ago — no writes in 90d" as the reason. Evidence a reviewer can read is what separates a recommendation from an opinion, the standard argued on the conflict-of-interest page — and it is what finally gets the perennial maybe-orphans off the monthly report and out of the bill.
See your own wasted cloud spend in minutes
Connect read-only, run a free scan, and get a prioritized list of savings with dollars attached.
What is the bottom line?
The Activity Log is the strongest, cheapest, most underused signal in cloud orphan detection. If your cost tool does not read it, you are reviewing the same list every month and acting on none of it. Bring in the last-touched data and the work changes from review to remediation — which is the whole point.