Cloud cost problems rarely begin with a single mistake. They are the compound result of small defaults: instances that survived a launch spike, snapshots with no lifecycle, services chatting across zones, and projects without clear ownership. This checklist is the pragmatic cadence we use with teams who need the bill to stop growing without slowing delivery.

Why cloud bills grow: architecture, utilization, pricing, and process

Most invoices expand for four boring reasons. Architecture: a system sits in the wrong place or uses a heavyweight service for a simple job. Utilization: capacity was sized for the worst day and never revisited. Pricing: commitments and spot capacity go unused. Process: nobody owns tagging or expiration, so waste persists. Read your own bill against these four buckets and write the first three fixes that would lower each one.

Monthly quick wins

A short checklist teams actually run

  • Terminate or hibernate idle instances older than 30 days.
  • Downsize instances with CPUUtilization p95 under 40% for two weeks.
  • Enable lifecycle rules: S3 to IA/Glacier, logs with 30–90 day expiry.
  • Kill unattached EBS volumes and orphaned snapshots.
  • Tag owner and purpose; quarantine resources without both.

A pragmatic monthly checklist (with quarterly deep dives)

Run the quick list above every month, then reserve one quarterly session for deeper moves: consolidate low‑traffic services, move steady internal apps to flat‑rate hosting, and replace per‑GB network chokepoints. Keep the cadence short, visible, and owned by a named person. A standing 45‑minute review outperforms an annual “FinOps initiative” that never ships.

Tagging and allocation engineers will actually use

Tagging fails when it demands a taxonomy nobody remembers. Start with two enforced tags: owner (team or person) and purpose (service or project). Quarantine resources without both. Keep cost allocation simple: a top‑level split by product or business unit is enough to make directionally correct decisions. Once owners see their own line item, unowned waste stops being invisible.

Rightsizing & commitments

How to stop paying list price

WorkloadActionTarget
Steady 24x7 DBConvert to Savings Plan / RIs60–80% coverage
Web tierRight-size family + autoscalep95 CPU 50–70%
Batch/ETLSpot with interruption handling70% spot mix
Dev/QASchedules + stop at night/weekends40–60% runtime cut

Rightsizing that shows up on the bill

Right‑sizing works when you pick targets and automate the signal. Track p95 CPU for the last two weeks; anything under 40–50% is a downgrade candidate. Prefer newer instance families for better price/perf. For steady 24×7 services, use Savings Plans or reserved capacity—coverage near zero is the same as paying list price. Batch and ETL jobs can often run on spot with interruption handling. Dev and QA should not bill at 3 a.m.

Look at memory, IO, and connection limits too. A CPU graph at 60% can mask a database constrained by IOPS or a JVM running near max heap. Prefer fewer, larger instances over many tiny ones when inter‑service chatter is your constraint; prefer smaller instances when bin‑packing spreads work across AZs you already pay for. Measure before and after, and keep a short changelog so the same debate does not repeat every quarter.

Storage classes and retention: write the policy once

Data grows forever unless you tell it not to. Add lifecycle policies the day a bucket or log group appears: objects move to IA or Glacier after 30–90 days; logs expire. Review snapshot chains older than ninety days and keep only what recovery requires. The hour you spend here prevents the silent, year‑over‑year growth that buries budgets.

Backups are not archives. Keep restorable points that match your recovery plan, then move everything else to colder classes or delete it. For analytics buckets, partition by date and expire old partitions. For logs, aggregate to daily or hourly parquet and expire raw streams after your investigation window. These moves lower cost and improve query speed at the same time.

Data transfer

The quiet line items to check

  • NAT Gateway processing vs. interface endpoints (PrivateLink).
  • Cross‑AZ chatter: co‑locate heavy talkers or use same‑AZ services.
  • Egress from object storage or CDN misconfiguration.
  • Uncached service‑to‑service calls across regions.

Data transfer: the quiet line items

NAT Gateways charge per GB processed; cross‑AZ traffic charges in both directions. Both can exceed the compute under them. Replace NAT paths with interface endpoints for chatty services. Co‑locate heavy talkers. Cache or batch cross‑region calls. Read the Cost and Usage Report specifically for these items; they hide in plain sight.

Cost‑aware SDLC: budgets in CI/CD and pre‑deploy checks

Make budget checks part of delivery. Add a terraform plan cost estimate gate before merge. Fail deploys that add resources without required tags. Provision short‑lived review environments with TTLs. Capture service‑level budgets in dashboards alongside latency and errors. If cost is not visible where engineers work, it will not change.

Governance: who owns what, and how to keep it from backsliding

Write down ownership: which team holds the cloud account, the networking boundary, the database fleet. Give the monthly review a single accountable owner. Document three stop‑conditions that pause deploys: budget burn rate, error budget burn, and a security finding above your risk threshold. If you need outside help, our AWS cost optimization review starts with the same evidence and leaves you with policies the team keeps.