Est.

Identifying and Eliminating Cloud Waste in Production Environments

Most cloud teams can't see their idle resources, so they can't eliminate them.

Staff Writer · · 12 min read · Updated
Cloud Cost Optimization · August 10, 2026 · 12 min read · 2,636 words

The median EC2 instance runs at somewhere between 7% and 12% CPU utilization. Not during slow periods. As a median, across all hours, all workloads, all environments. It means the typical instance is idle for the vast majority of its paid runtime, and the team paying for it almost certainly doesn't know that in any real-time, actionable way.

Kubernetes clusters compound this badly. CNCF's 2024 FinOps Survey puts average CPU utilization across clusters around 10%, with memory averaging around 20%. The mechanism is almost tediously predictable once you've seen it a few times: teams set resource requests conservatively for safety, the scheduler reserves that capacity in full, and actual consumption lands far below what's been reserved. The cluster looks nearly full on paper. It's running mostly air.

Then there's the zombie resource problem. Microsoft's Azure waste analysis found that roughly 35% of Azure resources have seen no meaningful activity in 90 days, and 73% of Azure VMs are oversized by at least one SKU tier. Seventy-three percent is not an outlier category; it is the norm. Overprovisioning isn't something that happens to undisciplined teams. It is the default behavior of virtually every team that hasn't built systematic revisitation into its process, which is most teams.

Dev and test environments sit on top of all this. They generate waste at more than double the rate of production, largely because no one configured automated shutdown policies. A developer works eight hours. The dev environment runs around the clock.

None of this is accidental sprawl. It's structural, baked in at the moment of initial deployment and preserved by organizational inertia. Teams provision for peak, run at a fraction of that peak, and the gap just sits there, billing continuously.

Why most engineering teams can't see the waste they're generating

Most teams aren't generating this waste out of indifference. They genuinely can't see it, and there's a meaningful difference.

Fewer than half of developers have access to real-time data on idle resources. Fewer than 40% have visibility into orphaned resources. Only about a third can see over- or under-provisioned workloads in their own environments. Some platforms build autoscaling and resource visibility into the deployment layer so teams aren't starting from blind. Harness's 2025 FinOps in Focus survey found that 52% of engineering leaders identify the disconnect between FinOps and development teams as a direct cause of wasted spend. Not a discipline problem. Not a culture problem. An information problem.

Roughly 70% of large enterprises have a dedicated FinOps function, which sounds encouraging until you notice who that leaves out. Startups, growth-stage companies, mid-market organizations: these are the teams making cost decisions without the institutional infrastructure to make them well. Mid-market companies, broadly those in the 500-to-5,000 employee range, are in a particularly punishing position. Their cloud spend is large enough that waste is materially expensive, but their organizational maturity hasn't caught up to systematic cost governance.

Poor resource tagging makes the attribution problem concrete. Environments with weak tagging carry waste rates roughly 40% higher than well-tagged environments, per Azure cost management data. Waste without an owner is waste that persists indefinitely. No one can take responsibility for a resource they cannot identify.

The fix here is not hiring a FinOps team. It's building visibility infrastructure. A minimum tagging schema, cost allocation by team and environment, a regular reporting cadence. Teams that receive weekly cost reports reduce spend measurably more than teams operating on monthly billing reviews. Weekly feedback loops close the gap between provisioning decisions and their financial consequences. Monthly reviews mostly document damage that's already done.

The first 30 days: finding and killing the obvious waste

A focused first-30-days effort typically recovers between 5% and 8% of total cloud spend through actions that require no rightsizing analysis, no reserved instance commitments, and no advanced tooling. Pure cleanup. This is where you go first, every time.

Start with the zombie resource audit. Pull every resource with no meaningful activity in the past 90 days, tag ownership, and schedule deletion reviews. Given that roughly 35% of Azure resources fall into this category, the yield is immediate and substantial. Unattached EBS volumes, orphaned snapshots, outdated AMIs: these are pure carry cost with zero operational upside.

Dev and test instance scheduling is the next lever. A dev environment running 24 hours generates a theoretical 67% waste rate on compute. AWS Instance Scheduler, Azure Automation, and comparable tools can implement automated start/stop schedules in two to four weeks. The expected recovery lands somewhere between $0.08 and $0.15 per dollar of dev spend, and it compounds quickly across a team running multiple environments simultaneously.

Run a tagging sprint in parallel. Establish a minimum schema before adding any new resources: team, environment, owner, cost center. Retroactive tagging is significantly harder than upfront policy, and every untagged resource added going forward widens the attribution gap driving that 40% higher waste rate.

These actions are executable by any engineer with cloud console access and a few weeks of focused time. No special tooling. No organizational restructuring. Just the decision to prioritize them, which is, admittedly, where most teams stall.

Rightsizing compute: moving from cleanup to structural reduction

By the 90-day mark, teams that layer rightsizing onto their initial cleanup typically reach between 12% and 18% total waste reduction. This phase addresses the structural problem that cleanup leaves intact: most compute is provisioned larger than any workload actually requires, and it was provisioned that way on day one.

The process is straightforward in principle. Pull two to four weeks of CPU, memory, and network utilization metrics. Compare against current instance specifications. Downsize to the smallest instance that preserves meaningful headroom above the 95th percentile of observed usage. That 95th percentile framing is the part teams most commonly botch. Teams that rightsize against peak utilization instead of the 95th percentile simply recreate the overprovisioning bias at a slightly smaller instance size. Better, but structurally similar to where they started.

Once a workload is rightsized, reserved instance commitments and savings plans become the appropriate next lever. The sequence is non-negotiable: commit after rightsizing, never before. Committing to a one-year reservation on an oversized instance locks in the overspend for the full term. Spot instances are viable for stateless, interruptible workloads, including batch processing, CI runners, and non-latency-sensitive background workers, all of which can absorb interruption in exchange for substantial cost reduction.

All of this depends on ownership tagging. Teams cannot rightsize what they cannot attribute. That 40% higher waste rate in poorly tagged environments is a direct consequence of skipping the earlier step, and it surfaces here, visibly, as work you cannot do.

Cutting Kubernetes waste specifically, since clusters are where headroom disappears quietly

Kubernetes deserves its own treatment because the waste mechanics differ from raw EC2 in ways that make standard utilization reviews insufficient. The failure mode is particularly insidious: the cluster looks healthy right up until the bill arrives.

Here's how it works. Teams set resource requests high for safety. The scheduler treats those requests as hard reservations. Actual pod consumption sits far below the reserved capacity. The dashboard shows high allocation, which registers as good utilization, but allocated capacity and consumed capacity are not the same thing. A cluster running at 10% CPU and 20% memory utilization, which is what CNCF's 2024 survey found, is running mostly empty while billing for mostly full. Because the dashboard says "allocated," the problem can go unexamined for months.

Vertical Pod Autoscaler addresses this at the pod level. It monitors actual resource usage and adjusts requests accordingly, removing the manual revisitation step that teams consistently skip under delivery pressure. Horizontal Pod Autoscaler handles the traffic variability that drives overprovisioning in the first place, scaling replicas based on observed metrics rather than anticipated peaks that often never materialize.

At the node level, cluster autoscaler and node rightsizing work toward the same goal: matching node pool instance types to the actual workload mix rather than provisioning generously and hoping the scheduler fills the space efficiently. Bin-packing, consolidating pods onto fewer nodes during low-traffic periods, requires explicit configuration. Kubernetes does not do this automatically, and it will not warn you that it isn't doing it.

Namespace-level cost visibility is the governance layer that makes everything else self-reinforcing. Shared clusters without namespace cost attribution create diffuse accountability. Everyone uses the cluster; no one owns the bill.

Storage and data transfer: the costs that grow invisibly alongside compute

Storage and data transfer waste operate on a different growth pattern than compute. They accumulate quietly, they don't surface in utilization dashboards, and they're rarely part of the architecture conversation when initial design decisions get made.

Unattached EBS volumes, orphaned load balancers, forgotten object storage buckets: no workload, no value, billing continuously. The cleanup logic mirrors compute. Identify, tag, review, delete.

The longer-term structural issue is lifecycle policy, or rather its near-universal absence. Most teams set no lifecycle rules on object storage. Objects written to S3, GCS, or Azure Blob sit in premium storage tiers indefinitely, regardless of how frequently they're accessed or whether they're accessed at all. Transitioning objects to infrequent-access or archive tiers after defined periods is a configuration change, rather than an engineering project. The cost differential between tiers is substantial for data that's sitting untouched, and yet this step gets skipped constantly.

Egress charges are the most consistently underestimated cost category in cloud architecture. Data leaving a region or crossing availability zones generates transfer fees that almost never appear in initial design discussions. Multi-cloud environments carry the highest waste rates partly because cross-provider data transfer costs are multiplicative and difficult to attribute after the fact. Including egress patterns in regular utilization reviews catches these charges before they compound into a line item that surprises a CFO.

Snapshot retention is a specific and entirely predictable leak. Automated snapshots without automated deletion create unbounded storage growth. A weekly snapshot retained indefinitely is a cost that is completely foreseeable and almost never modeled explicitly. It's the kind of thing you notice when someone finally runs the numbers and asks why storage costs keep climbing on a workload that hasn't grown.

AI and GPU workloads need their own waste elimination logic

Flexera has attributed rising cloud waste in part to AI adoption outrunning cost-governance habits, and the mechanism is worth understanding precisely, because the standard FinOps playbook wasn't built for these workloads.

Inference now represents the dominant share of AI infrastructure spending, having overtaken training costs as models move from development into production, per Andreessen Horowitz's 2024 AI infrastructure analysis. Teams that built their cost models around training budgets are discovering that inference at scale is the larger and less predictable expense. A training-focused FinOps framework wasn't designed to catch that shift.

GPU idle time is the core waste vector for inference workloads. A GPU instance reserved for serving requests but sitting at low utilization between requests costs identically to one running at capacity. The per-hour price of GPU compute is substantially higher than CPU-based instances, which means idle GPU time is just more expensive idle compute.

The efficiency levers on the inference side are model-level, rather than just infrastructure-level, and this is where a lot of teams leave savings untouched. Batching inference requests, quantizing models, and matching model size to actual accuracy requirements all reduce GPU hours consumed without degrading output quality. These optimizations are often more impactful than instance rightsizing because they reduce the load presented to the GPU, rather than just the size of the GPU provisioned. Infrastructure rightsizing and model-level efficiency are both necessary; doing one without the other is a partial solution that feels like a complete one.

Spot and preemptible GPU instances remain viable for training workloads that implement checkpointing. The savings are substantial for non-latency-sensitive batch jobs, and the interruption risk is manageable when training jobs are designed to resume from a saved state. Managed ML platform surcharges from major hyperscalers are also worth quantifying explicitly before defaulting to a managed service. The convenience premium can be significant, and for teams with the operational capacity to run their own serving infrastructure, the math often favors self-managed deployment.

Apply the same utilization review discipline to GPU instances that applies to EC2. The workloads are different. The discipline is identical.

Automation and guardrails that prevent waste from returning after cleanup

Cleanup is a starting point, rather than a strategy. Without automation and structural guardrails, waste returns as fast as new resources get provisioned, because the provisioning behavior that generated the waste in the first place hasn't changed at all.

Organizations using FinOps frameworks are 2.5 times more likely to meet or exceed cloud ROI expectations, per the FinOps Foundation's State of FinOps report. Individual techniques produce one-time savings; governance infrastructure produces ongoing savings that scale with the workload.

Budget alerts and anomaly detection are the earliest warning layer. Catching a misconfigured deployment in its first week is categorically cheaper than discovering it at month-end billing. Alerts should trigger at meaningful spend thresholds, rather than just hard limits, so teams have time to investigate before waste accumulates into something significant.

Policy-as-code turns provisioning standards into enforcement mechanisms. Tagging requirements, instance type constraints, and environment schedules can be encoded at the infrastructure layer so that developers cannot accidentally provision out-of-spec resources. This removes reliance on manual review and human memory, both of which degrade reliably under delivery pressure. Mature tagging strategies reduce waste by 26% compared to untagged environments, per Azure cost management data. Teams treating tagging as optional are carrying a 26% penalty, whether they've noticed it or not.

Cost allocation as a team-level metric closes the organizational loop. When engineering teams receive weekly visibility into their share of the cloud bill, spend discipline becomes self-reinforcing. No external enforcement needed when the feedback loop is tight and the attribution is clear.

A realistic timeline for how much waste a team can actually recover and when

Each phase below builds the visibility and governance foundation the next phase actually requires. Skipping phases is how cleanup efforts fail to stick, and that pattern is depressingly common.

In the first 30 days, zombie resource cleanup, dev and test scheduling, snapshot audits, and a tagging sprint recover between 5% and 8% of total cloud spend. No specialized tooling. No organizational restructuring. Any engineer with cloud access and a few weeks of focused effort can execute them.

By 90 days, rightsizing and commitment coverage layered on top of that initial cleanup raise total savings to the 12% to 18% range. This phase requires utilization data and attribution, both of which the first phase puts in place. You cannot shortcut this by jumping straight to rightsizing; the data isn't there yet.

At six months, autoscaling, Kubernetes bin-packing, and storage lifecycle policies push total reduction into the 18% to 25% range. These are engineering projects, rather than configuration changes, and they require the governance infrastructure built in the earlier phases to remain maintainable as workloads evolve.

At twelve months, mature automation and guardrails sustain a run-rate that is 25% to 30% lower than the starting baseline. That outcome requires automation; manual reviews don't scale as workloads multiply and teams grow. The teams that reach and hold that outcome are the ones that stopped treating cost review as a periodic audit and started treating cost visibility as infrastructure, which is a genuinely different posture and harder to get to than it sounds.

A dedicated FinOps team is not required to reach the six-month milestone. Everything through that point is executable by any engineering team with the right reporting cadence and the discipline to use it. The twelve-month outcome is where platform-level automation earns its keep, because no team has infinite capacity to manually govern an environment that is continuously expanding. The teams that close the gap between provisioning and actual usage permanently are the ones that made the closure structural, rather than procedural.

Sources

  1. turbo360.com
  2. prnewswire.com

More in Cloud Cost Optimization