Waste Detection

Idle EC2: A Taxonomy of Waste

· Finopscraft
Abstract concept: taxonomy of idle cloud compute resources

Every FinOps tool has a metric called something like "idle compute." In AWS Cost Explorer, it's the Rightsizing Recommendations panel showing instances with low CPU utilization. In third-party platforms, it's usually a list of instances below some threshold, often 5% or 10% average CPU over 14 days.

The problem with treating idle EC2 as a single category is that the remediation path depends entirely on why the instance is idle. Stopping the wrong instance causes an incident. Stopping the right one saves $300/month and takes two minutes. Lumping them together means your engineering team either ignores the list entirely or has to manually investigate every entry before acting.

We've built Finopscraft's waste detection around a classification taxonomy rather than a flat list. This article explains the taxonomy and the reasoning behind each category.

Category 1: Orphaned Development Instances

These are instances that were spun up for a development or testing task and never terminated. They have no active users, no traffic, and no one who knows they exist. They often carry tags like env:dev or purpose:testing, or they're in a development account entirely.

Identifying signals: CPU below 2% for 14+ days, no inbound connections from application load balancers or target groups, last SSH session more than 21 days ago (from CloudTrail), running in non-production account or tagged dev/test/staging.

Remediation confidence: high. If an instance has had zero inbound traffic for three weeks and no human has SSH'd into it for three weeks, it is extremely unlikely to be serving any business function. Stop it, snapshot the root volume, wait 30 days, then terminate and delete the snapshot if nobody complained.

We flag these as "safe to stop" in the Finopscraft waste panel with a single-click stop action tied to a scheduled termination after a grace period. The grace period is configurable; most teams use 14 or 30 days.

Category 2: Forgotten Blue-Green Deployment Remnants

Blue-green deployments leave the old environment running for rollback capability. The problem is that rollback windows have a human-defined expiry that often gets forgotten. An old "blue" environment that was supposed to be deprecated 6 weeks ago is still running at full capacity.

Identifying signals: instance exists alongside another instance with the same application tag and similar configuration, one has substantially more recent deployment markers (from tags or CloudTrail events), traffic is flowing to only one of them, the older one has been receiving zero load balancer traffic for more than 14 days.

Remediation confidence: medium-high. You need to confirm with the team that the rollback window has expired before stopping. We don't auto-stop these because the blast radius of incorrectly stopping a "blue" environment that's still in the rollback window is high. We flag them with a question: "Blue-green remnant detected. Is this still within your rollback window?"

The key distinction from orphaned dev instances is that these were intentionally left running as part of a deployment process. The waste is structural, not accidental. Without explicit process automation to clean up old environments, they accumulate fast. A team doing weekly deployments with a 2-week rollback window will have at most 2 old environments live at any time; a team with no cleanup automation will have as many as they've shipped features in the past year.

Category 3: Load-Balanced Standby Instances

This is the most important category to get right, because incorrect classification here causes incidents. Autoscaling groups maintain warm standby instances at minimum capacity. These instances are technically "idle" in CPU terms but are not waste. They exist for availability: if traffic spikes, they're there. If you stop them, your autoscaling group minimum breaks and your fault tolerance degrades.

Identifying signals: instance is registered as a target in a target group, the target group shows the instance as healthy, the autoscaling group minimum capacity is set to a value that requires this instance to be running.

Remediation for this category is never "stop the instance." It's "review whether the autoscaling minimum is appropriate for your traffic pattern." If your minimum is set to 4 instances and you're regularly seeing 1-2 instances handling all traffic, the minimum might be over-provisioned. But that's a rightsizing conversation, not a waste termination action.

We're not saying standby instances are never worth addressing. We're saying stopping them directly is the wrong action. The right action is evaluating the autoscaling configuration, which requires understanding your traffic patterns, your acceptable time-to-scale, and your SLA. That's a human decision, not a one-click fix.

Category 4: Scheduled Workload Instances Running During Off-Hours

Some instances exist to run batch jobs, reports, or ML training runs on a schedule. Outside their scheduled windows, they sit idle. This is intentional architecture: the instance needs to be available when the job starts, but it runs for only 4 hours per day.

Identifying signals: CPU activity pattern shows regular spikes at consistent intervals with flat near-zero periods between. CloudWatch metrics show burst-then-idle cycles rather than continuous low utilization. Often tagged with purpose:batch or similar.

Remediation for this category is instance scheduling, not termination. Start it 5-10 minutes before the scheduled job window, stop it after completion. AWS Instance Scheduler, Systems Manager automation, or a Lambda-triggered schedule can handle this. For a c5.2xlarge running 4 hours per day instead of 24, you reduce compute cost by roughly 83% on that instance.

We flag these separately in Finopscraft with the label "scheduling candidate" rather than "waste," and we generate a pre-built EventBridge rule configuration that the team can deploy directly.

Category 5: Overprovisioned but Active Instances

These are not idle in the traditional sense, but they're a meaningful waste category. An instance consistently running at 8-12% CPU and 20% memory utilization is not idle, but it's also not using the resources it's paying for. A rightsizing recommendation from r6g.2xlarge to r6g.large can save 50-60% of the compute cost with no degradation in performance.

The challenge with rightsizing is that peak utilization matters, not average. An instance that runs at 10% CPU on average but spikes to 80% for 30 minutes daily during a batch job cannot be rightsized to a smaller instance without potentially saturating during that spike.

We evaluate 95th percentile utilization over a 30-day window, not average. We only recommend rightsizing when 95th percentile CPU is below 40% and 95th percentile memory is below 50%. This leaves a meaningful headroom buffer and means our recommendations are safe to act on without detailed per-instance investigation.

Why Taxonomy Matters for Showback and Chargeback

If you're running a chargeback or showback model where teams see their own cloud costs, the taxonomy matters beyond just which button to click. Category 1 (orphaned dev) is pure waste attributable to a specific team. Category 2 (blue-green remnants) is waste from a process problem, potentially attributable to a deployment practice. Category 3 (standby instances) is not waste at all, even though it looks like idle compute.

Showing a team a showback report that lumps all of these together as "idle EC2 cost" creates confusion and distrust. They'll look at their Category 3 standby instances, know those are intentional, and decide the whole report is wrong. Getting the taxonomy right makes the waste flags credible, which makes the engineering team more likely to act on the ones that are genuinely actionable.

The classification logic in Finopscraft runs across CloudWatch, CloudTrail, EC2 target group membership, and tag data to assign each idle instance to one of these categories before surfacing it in the waste panel. This doesn't make the engineering work go away, but it makes sure the work that does land in front of an engineer is work they can actually do something about.