← Articles

Cloud cost optimization

Cutting engineering cost by 20% by making cloud spend visible, owned and reviewed, without trading away reliability or delivery speed.

Use casesUse case 5 of 72 min read

FinOpsCost allocationGCPAWSAzureKubernetesTerraform

Cloud bills grow the same way garden weeds do: a little at a time, everywhere at once, until one day you look up and there’s a problem. Spend had grown with the business, which is normal. What wasn’t fine was that nobody could say what any single product or customer actually cost to run. Without that, there’s no way to tell useful spend from waste.

Step one: make cost visible

You can’t optimize what you can’t see. Before changing a single resource, we made spend attributable:

  • A tagging and labeling standard applied across all three clouds: product, environment, customer and owner.
  • Tags enforced in Terraform, so new resources couldn’t be created without them.
  • Cost allocation mapping spend to projects, and also to operating versus capital budgets. Engineering time spent building products was recorded correctly against capital projects, which finance cares about as much as the cloud bill.

Once spend had owners, the conversations changed. “The cloud bill is high” became “this environment costs this much a month, and here’s who owns it.”

Step two: find the waste

With visibility in place, the waste was easy to see. It usually falls into a few buckets:

  • Over-provisioned compute, sized for a peak that never came.
  • Non-production environments running 24/7 when they’re only used during working hours.
  • Orphaned resources, such as unattached disks, old snapshots and idle load balancers left over from past projects.
  • Storage on the wrong tier, with rarely read data sitting on expensive, high-performance storage.
  • Steady workloads on on-demand pricing that could use committed-use or reserved pricing.

Step three: fix it, carefully

Each fix was a normal, reviewed infrastructure change, not a cost-cutting sprint that breaks things:

  • Right-sizing based on observed usage, with headroom kept for real peaks.
  • Scheduling non-production environments to scale down outside working hours.
  • Lifecycle policies that move aging data to cheaper storage tiers automatically.
  • Commitments only for steady baseline usage, never for spiky or experimental workloads.
  • Architecture changes where they paid for themselves, such as moving bursty work onto autoscaling or managed services.

The constraint throughout was simple: reliability and delivery speed don’t get worse. A saving that causes an outage isn’t a saving.

Step four: make it stick

One-off cleanups decay. Costs creep back unless reviewing them is part of normal work:

  • Monthly cost reviews per product, with owners walking through trends and anomalies.
  • Budget alerts that go to the owning team, not just to finance.
  • Cost considered at design time. New architecture proposals include an estimate of what it will cost to run.

The result

Engineering cost came down by 20%. More importantly, the organization could finally see where its money went, and the teams spending it owned it.

What I’d tell another team

  • Tag first and enforce tags in code. Everything else depends on it.
  • Start with non-production. It’s usually the biggest, safest win.
  • Only commit to what’s steady. Discounts on unused capacity are just waste.
  • Make cost a recurring conversation, not a yearly fire drill.
Outcome

Engineering cost down 20%, with the visibility and habits in place to keep it there.