Cloud Cost Optimization: Don't Let the Bill Eat Your Profits
On the cloud it's easy to 'get more expensive as you use it' — idle resources, over-provisioning, forgotten services, traffic fees. Covers cost optimization levers: compute (reserved/spot/right-sizing), storage (tiering/cleanup), network (egress/CDN), bill monitoring + alerts, and the 'FinOps' culture making costs visible and accountable.
Key Points
- Topic Focus: DevOps
- Suitable for: indie hackers, full-stack engineers, AI application developers
- Core value: quickly understand background, practical paths, common pitfalls, and engineering advice
The day a business moves to the cloud, the most common thing the boss says is "now we don't need to buy servers, we'll save money." Three months later, when the bill lands on the CFO's desk, the mood changes — why is this month 40% more than last month? Why do we have a test environment machine that costs more than production? Why did someone run a batch job at 3 AM and double the data transfer fee?
The cloud bill is like boiling a frog in warm water. It doesn't hit you with a one-time CAPEX that makes your heart ache like building your own datacenter; instead, it deducts a little bit every day, and by the time you come to your senses, a big chunk of profit has already been gnawed away. This article explains cloud cost optimization thoroughly: why it spirals out of control, the most effective levers, and how to use monitoring and FinOps culture to keep costs in check.
One: Why Cloud Costs Easily Spiral Out of Control
First, understand the cloud's billing logic. The cloud is the product of three things combined: pay-as-you-go + elasticity + hidden fees:
- Pay-as-you-go means "the more you use, the more you pay," which sounds reasonable, but it assumes "you'll actively manage usage" — most people don't.
- Elasticity means "get as much as you want," so everyone habitually over-provisions, "in case a traffic spike comes and we can't handle it."
- Hidden fees are the real killer. CPU, memory — you can see those, but cross-region traffic, NAT gateways, load balancers, public IP occupancy, managed services billed per-call — these hide in the corners, inconspicuous day-to-day, and by month-end when you pull the bill they can take up thirty percent.
A typical scenario: an engineer spun up 5 machines for testing, forgot to shut them down after testing, nobody checked over the weekend, and Monday morning they find they spent hundreds of dollars. Multiplied by N teams, N environments, 365 days, that's a big bill.
This is the backdrop against which FinOps arose. FinOps = Financial Operations, the philosophy comes from DevOps — bringing finance, engineering, and business to the same table, making cost as visible, accountable, and optimizable as CPU utilization. It's not a money-saving campaign; it's "making everyone who spends cloud money know how much they're spending and why."
Two: Compute: The Reserved, Spot, Right-Sizing Trio
Compute is usually the bulk of the cloud bill (60-80%), and has the most levers. Three things are must-dos:
First, Reserved Instances / Committed Use Discounts. Your databases, core APIs, always-on services — these are stable workloads running 24/7, and using on-demand billing for them is wasteful. AWS's Reserved Instances / Savings Plans, GCP's Committed Use Discounts, Azure's Reserved VM Instances are all essentially the same thing — you commit to one or three years, in exchange for a 30-70% discount.
In practice, first spend a month observing "which instances are running 24/7," migrate those to reserved, and the bill immediately takes a cut. But don't lock in for three years right out of the gate — the tech stack is changing, and locking too tightly means forfeiting the value of flexibility. One year is usually the cost-effectiveness sweet spot.
Second, Spot Instances / Spot Instances. Batch processing, training jobs, CI runners, nightly ETL — these interruptible workloads should go straight to Spot. The principle is that the cloud provider sells you idle capacity cheaply, but the price is "I can take it back at any time." Discounts can reach 70-90%, the cost being possible interruption.
The correct way to use Spot is a queue + checkpoints: save intermediate state before the task runs, so if interrupted it can resume from the breakpoint; form a queue from multiple instance types, so if one gets reclaimed, switch to another AZ and keep going. Stateless, retryable, horizontally-scalable tasks are all suitable; don't use it for online services — the experience of a user request getting interrupted is more expensive than the money saved.
Third, right-sizing. This is the highest-ROI but worst-done thing. The vast majority of cloud machines are over-provisioned — CPU utilization hovering at 5-15% long-term, memory usage under 30%, but the machine spec is set based on "peak assumption."
# Use CloudWatch / Cloud Monitoring to pull the last 30 days of utilization
# Look at p95 CPU, p95 memory, not averages
# Rule of thumb: if p95 < 40% for 14 consecutive days, drop one tier
# Database connection pools take up most of the memory; before downsizing the machine, first check whether the connection count has been tuned
Right-sizing should be looked at by p95, not average — averages get dragged down by nighttime troughs. A common practice is to drop one tier and observe for a week, and if stable, drop another, until pressure signals appear and then stop. An m5.2xlarge dropping to m5.large is a 50% difference; multiplied across dozens of machines in a cluster, that's real money.
Three: Storage: Tiering, Cleanup, Lifecycle
Storage costs are often underestimated — cheap per GB, but staggering when accumulated, and unmanaged storage only grows, never shrinks.
Tiered storage is the foundation. AWS S3 / GCS / Azure Blob all support tiering: hot tier (frequent access) is expensive, cold tier (Infrequent Access / Coldline) is cheap, archive tier (Archive / Glacier) is extremely cheap but costs money to retrieve.
Hot data (accessed within last 7 days): Standard tier
Warm data (occasionally accessed within a month): IA / Nearline
Cold data (compliance retention, almost never read): Archive / Glacier
Configure lifecycle policies for automatic migration: 30 days after object creation, move to IA; after 90 days, move to archive. Write the rules once, and new data automatically follows them afterward. A company with PB-scale cold data can save six figures just from tiering.
Cleaning up unused resources is another fat target. The easiest to forget:
- EBS / Persistent Disk snapshots: daily automatic snapshots, deleted the instance but forgot to delete the snapshot policy, and a year later hundreds of GB of orphan snapshots are lying around. Periodically run
describe-snapshotsto find "the corresponding volume has been deleted" ones, and clean them up. - Unattached volumes: deleted the instance, kept the volume — this is a classic leak. Scripts scan for
volume-state == availablefor more than 7 days, and clean directly. - Old images / AMIs: store one per build, hundreds after a year, each with a snapshot hanging behind it. Keep the most recent N, deregister the old ones and delete the snapshots.
- Unused load balancers, idle public IPs: LBs are billed hourly, public IPs are charged hourly even when not attached to an instance — these are pure waste.
Run a resource audit script once a week; this is the most direct money-saving measure.
Four: Network: Egress Traffic Is the Hidden Bill
Many people only realize at month-end: the cloud's network fees aren't calculated by "how much bandwidth you used," but by "how much data flowed out." And the prices for cross-region, cross-cloud, and out-to-internet vary wildly.
- Same-region, same-AZ communication: basically free or very cheap.
- Cross-AZ: a little bit, charged both ways (both in and out).
- Cross-region: expensive; a few GB can cost tens of dollars.
- Out to internet (egress): the most expensive; a few cents to a dollar per GB; large download scenarios directly eat into profit.
There are three levers:
First, use a CDN to save origin fetches. Put static resources (images, JS, CSS, video) on a CDN (CloudFront, Cloud CDN); users fetch from edge nodes, greatly reducing traffic that fetches back to the origin server. CDN traffic unit price is lower than the origin server's egress, and the user experience is better (accessed nearby). A site heavy on images using a CDN can often cut egress traffic fees by more than half.
Second, same-region deployment saves cross-region fees. Put the database and application in the same region and same AZ; inter-service calls don't go cross-region. In a microservices architecture, once the call chain gets long, cross-region traffic multiplied out gets terrifying. If you have multiple regions, each region should come with its own complete local dependencies (DB replicas, cache), rather than querying cross-region.
Third, plan data egress. Need to export large amounts of data to customers or partners? Consider physical export (AWS Snowball, GCP Transfer Appliance) to haul it away at once, cheaper than over the network. Or run analysis-type workloads directly in the cloud where the data lives (when sending reports to customers, only send aggregated results, not raw data).
Five: Managed Services: Don't Use Expensive Ones for Convenience
Cloud providers are happy to sell you managed services — RDS, ElastiCache, managed Kafka, managed K8s... they do save trouble, but they're expensive. The same Redis, self-hosted community edition vs. managed edition, can differ in price by 2-4x.
To decide whether to use managed, do the math:
- Managed premium = managed price - self-hosted hardware cost
- Self-hosted operations cost = labor + high-availability solution + backup/restore + monitoring/alerting
If the managed premium is far higher than the operations cost, self-hosting is more cost-effective; if the operations cost is high enough to require dedicated staffing, managed is more cost-effective. Small teams, non-core components — managed saves trouble; core components, once at scale, self-hosting is often cheaper, and the technical capability accumulates.
But there's a counterexample to watch out for: don't self-host a database on a cloud VM just to save money. Database high availability (master-slave failover, automatic backup, disaster recovery) is easy to get wrong doing it yourself; losing data is ten thousand times more expensive than the money saved. For stateful, strongly-consistent, can't-afford-to-lose services like databases, use managed when you should.
Stateless services (cache, queue, compute nodes) are suitable for self-hosting or open-source solutions, because even if they go down, restarting brings them back. Stateful services managed, stateless services self-hosted — this is a good starting posture.
Six: Monitoring: Cost Dashboard, Cost Allocation, Anomaly Alerts
You can't optimize what you can't see. The foundation of cloud cost optimization is monitoring, and you need to monitor the bill like you monitor CPU.
Cost dashboard: use the cloud provider's Cost Explorer / Cloud Billing, or the open-source CloudCust (OpenCost), to build a Grafana dashboard, sliced by service, by team, by resource type. Looking once a day is more useful than looking at the monthly bill — by the time the bill arrives, it's already too late.
Cost allocation by team/project: this is a key engineering action. Use tags/labels to mark each resource with team=payment, env=prod, project=checkout, then aggregate costs by tag. Enforce that all resources must carry tags (no tag, no creation — enforced with policy engines like AWS SCP, GCP Organization Policy). Without cost allocation, you can never explain "which team spent how much," and accountability is out of the question.
Anomaly alerts: a sudden bill spike must trigger an alert, not wait until month-end. Set two thresholds:
- Daily spend 50% higher than the past 7-day average → alert (someone may have spun up a big machine and forgotten to shut it down)
- Single-service spend 20% higher than budget → alert (possible traffic anomaly or resource leak)
Budget with alerts can catch "forgot to shut down machine" type things within 24 hours, rather than kicking yourself when next month's bill comes out.
Seven: FinOps Culture: Give Engineers Cost Awareness
All the tools are in place, but costs still won't come down? That's because engineers don't consider cost when making decisions — this is a culture problem, not a technical problem.
The three principles of FinOps culture:
- Costs are visible: every team's, every service's costs are on the dashboard, visible to everyone, not hidden in the CFO's drawer.
- Costs are accountable: how much a service cost, who's responsible — crystal clear; in quarterly reviews, put cost alongside performance and availability on the same table to align.
- Engineers have cost awareness: when making architectural decisions, don't just ask "is this design performant," also ask "how much does this design cost per month." Before spinning up a new machine, glance at utilization; before adding a new service, estimate the monthly cost.
Concrete actions to take:
- Bring cost into code review. PRs that add resources or change instance types get a glance during review for reasonableness. Add a cost estimate comment in CI: "this change is estimated to add $X per month."
- Cost challenge competitions. Give the team a goal — "this quarter, reduce cost per request by 20%"; reaching it earns a reward. Gamification beats lectures.
- Shared metrics. SRE and finance share one dashboard; let operations know where the money goes, let finance know why money is spent.
FinOps isn't a money-saving campaign; it's giving those who spend money the right to know, and giving those who decide a cost perspective. Like DevOps, it's essentially breaking down department walls — this time the wall between engineering and finance.
Summary
- The root of cloud cost spiraling is "pay-as-you-go + elasticity + hidden fees": the visible CPU isn't expensive; the invisible cross-region traffic, NAT, idle resources eat into profit. First understand the bill structure, then talk about optimization.
- Compute trio: reserved + spot + right-sizing: stable workloads lock in reserved discounts, interruptible tasks go to Spot, machines with low p95 utilization get firmly right-sized. These are the three highest-ROI steps.
- Storage relies on tiering + cleanup: hot/warm/cold auto-migration, lifecycle policies written once; orphan snapshots, unattached volumes, old images are pure waste; audit once a week.
- Network optimization's core is reducing egress traffic: use CDN to save origin fetches, same-region deployment to save cross-region, plan data egress; going out to the internet is one of the cloud's most expensive unit prices.
- FinOps is culture, not tools: costs visible, accountable, engineers have cost awareness; monitor the bill like a metric; turn "saving money" into an engineering habit.
One-sentence closer: Money on the cloud isn't saved, it's managed — make cost a first-class engineering metric, and you won't be doubting your life over the bill at month-end.
Related
Related Content
Article
Considerations for Deploying a Next.js Community Project with Docker
Technical trends, engineering practices, and an independent developer perspective on DevOps and Next.js.
Article
How Can OpenTelemetry Help You Observe AI Applications?
Technical trends, engineering practices, and an independent developer's perspective on DevOps and AI.
Article
Long-Running Tool Calls: The Terminal-State Protocol for Operation, Poll, and Cancel
After the initial request times out, the tool may still be running server-side; issuing a cancel does not mean the side effects have stopped. This article establishes an operation identity, polling watermark, cancellation race handling, and a single terminal-state acceptance point for a single long-running tool call.
Article
Agent Memory Erasure Propagation: From User Forgetting Request to Verifiable Purge
Deleting one row in the primary table won't clear vectors, summaries, caches, or restored backups. This article uses a deletion state machine, generational tombstones, derived lineage, and end-to-end canary verification to truly forget.