Skip to content
root@hisham:~/blog/posts$ glow cloud-spend-80.md
cloud-spend-80.md
· 8 min read · infra

# Cutting cloud spend by 80% without cutting anything users notice

Where the money was actually going across AWS, Azure, and Railway, which line items were safe to delete, and the measurements I took before touching production.

The bill was not one large mistake. It was forty small ones, each of them defensible on the day it was made, none of them revisited afterwards. Staging environments that outlived their projects. Managed databases sized for a launch that never came. Three clouds, because three teams each picked the one they knew.

## Measure before you delete

Before changing anything I tagged every resource by owner and project, then exported a month of billing data and grouped it by tag. Roughly a third of the spend had no owner at all. That third is where the work started, because nothing without an owner has a user waiting on it.

# untagged resources, sorted by cost
$ aws resourcegroupstaggingapi get-resources \
    --tags-per-page 100 | jq -r '.ResourceTagMappingList[]
    | select(.Tags | length == 0) | .ResourceARN'

## The four changes that mattered

  • Consolidated environments. Every project kept production and one shared staging. Ephemeral preview environments replaced the permanent ones, created per pull request and destroyed on merge.
  • Right-sized the databases. Peak connections and working-set size, measured over four weeks, argued for instances two tiers smaller than the ones we were paying for.
  • Moved steady-state workloads off per-request pricing. Services with predictable traffic run cheaper on a fixed box than on anything metered.
  • Replaced the hosted analytics. A self-hosted Umami instance covers the questions the marketing site actually asks, for the price of the smallest VM in the fleet.
The savings came from deleting things nobody was using, not from making anything worse for the people who were.

## Proving nothing broke

Each change shipped behind the same checks: p95 latency and error rate compared against the previous week, a post-deployment health check in CI, and a rollback path that took one command. When a smaller database instance did push p95 up on one service, we moved it back a tier and kept the other nine.

monthly spend
−80%
clouds in use
3 → 2
p95 latency
unchanged
incidents caused
0

## What I would do earlier

Tagging on creation, enforced in the provisioning pipeline rather than added later by hand. A monthly cost review in the same meeting as the incident review. Both are cheap habits that would have made this a twenty-minute report instead of a quarter of cleanup.

Questions or corrections: hishammedhat0@gmail.com github
root@hisham:~/blog/posts$