preloader
post-thumb

Last Update: September 3, 2026


BYauthor-thumberic

|Loading...

Keywords

Our monthly Google Cloud bill came in at just over 600 dollars. Nothing was on fire, no traffic had spiked, and no new service had launched. The bill had simply crept up, one reasonable-looking decision at a time.

So we sat down and audited it, line by line. By the end we had a plan that cut the bill by more than half, without leaving the cloud, without moving regions, and without giving up anything we actually used. Almost all of the savings came from understanding settings — the dials that cloud platforms leave on their most convenient default rather than their cheapest one.

Here is what we learned.

Read the bill like a map, not a total

The single most useful thing we did was stop looking at the total and start grouping every line item by what it actually was. Google's cost table breaks charges into dozens of tiny SKUs — "CPU (request-based billing)", "SSD backed PD capacity", "network inter-region data transfer" — and on their own they mean very little. Grouped by cause, a shape appears fast.

When we did that, one pattern jumped out immediately:

Where the money went
Roughly
What it actually was
One background workload
About 60%
A fleet of small agents writing to the database on a timer
Web serving
A chunk
Cloud Run handling real requests
Always-on worker
Around 50 dollars
A container that could never scale to zero
One database server
Around 90 dollars
A virtual machine sitting almost completely idle
Small stuff
The rest
Logs, disks, snapshots, an orphaned IP address

The lesson of the audit was almost boring: one workload was 60% of the bill. Everything else combined — every website, every API, every bit of storage — was the minority. If you only have time to fix one thing, find your elephant first.

Cloud Run is cheap, until a setting says otherwise

We love Cloud Run. It scales to zero, you only pay when it runs, and you never patch a server. But "you only pay when it runs" hides two settings that decide whether that promise holds.

Minimum instances

By default a Cloud Run service scales to zero when no one is using it. Set a minimum number of instances above zero and you are asking Google to keep that many copies warm at all times — which removes cold starts, and bills you around the clock whether or not a single request arrives.

Setting
What it does
What it costs
Min instances = 0 (default)
Scales to zero when idle
Nothing when idle; a cold start on the first request
Min instances = 1 or more
Keeps copies always warm
You pay for those copies 24/7, including while you sleep
CPU only during requests (default)
CPU is throttled between requests
Cheapest for normal request and response work
CPU always allocated
CPU keeps running between requests
Bills like an always-on VM, not per request

We had a couple of services quietly holding a minimum instance warm for a workload that saw almost no traffic. Setting them back to zero cost us nothing but a cold start once in a while, and removed the charge entirely.

The always-on trap

Here is the sharper lesson. One of our services was not a website at all. It was a background worker that holds a long-lived connection to a message queue and reacts to events. It has no incoming web requests to speak of — just a socket it needs to keep open.

That is exactly the workload Cloud Run is worst at. To keep the connection alive, it needs a minimum of one instance and CPU that is always allocated. In other words, it has to behave like a server that never turns off — while being billed as premium serverless compute. It cost around 50 dollars a month to do something a tiny always-on virtual machine, or a container on a machine we already ran, could do for close to nothing.

The rule we took away: serverless is brilliant for spiky, request-driven work that can genuinely go to zero. For anything that must stay awake all the time — a queue consumer, a poller, a persistent connection — check whether a small VM you already operate is cheaper. Often it is, by a wide margin.

When to self-host a database instead of using a managed one

This was the big one, and it is the least obvious.

Managed databases — Cloud SQL, Firestore, DynamoDB and friends — are wonderful. Backups, failover and scaling are handled for you. But many of them bill per operation: so much per read, so much per write. That pricing is fantastic when your traffic is small or spiky. It turns brutal when your workload is chatty.

Our background fleet was as chatty as it gets. Each agent wrote a small status update to the database on a fixed timer — every 30 to 60 seconds — whether anything had changed or not. Multiply a handful of writes per minute by hundreds of agents across a month and you land at hundreds of millions of tiny operations. On per-operation pricing, those cheap little writes added up to the largest single line on the whole bill.

The same writes, sent to a plain MySQL server running on a virtual machine we already operate, cost effectively nothing extra. The disk was already spinning; a few hundred million small writes a month is comfortably within what one modest server handles without noticing.

So when should you reach for each?

A managed database fits when
Self-hosting starts to win when
Traffic is small, spiky or unpredictable
Traffic is steady and high in volume
You would rather not run a server at all
You already run a VM with spare capacity
Per-operation cost is a rounding error
Your workload is chatty: many tiny reads and writes
You want managed backups and failover
You are happy to run your own backups
You are early and want to move fast
You are steady and want predictable, flat cost

There is a second reason we moved this workload onto our own database: portability. A plain MySQL server over a standard connection runs anywhere — another cloud, another region, your own hardware. Per-operation managed services are convenient precisely because they lock the shape of your data and your bill to one vendor.

A word of caution, because it cuts both ways: self-hosting means you own the backups, the patching and the 3am restart. We did not move a customer-facing production database off its managed home for a few dollars. We moved a high-volume, non-critical, internal workload where the maths was overwhelming and the risk was low. Pick your battles.

Two cheap habits also soften per-operation pricing without moving anything:

  • Write only on change. A status update that is identical to the last one does not need to be written at all. Debouncing our timer writes alone would have removed most of the volume.
  • Do not read to decide whether to write. It is easy to "save a write" by reading first — and end up paying for the read instead. On a chatty workload, reads can cost as much as the writes you were trying to avoid.

Right-size relentlessly

One database server on the bill cost around 90 dollars a month. We logged in to look at it and found the load average sitting at 0.00. Two dedicated CPU cores, 99% idle, around the clock.

We had sized it once, long ago, for a load that never arrived — and then paid for that guess every month since. Swapping it for a smaller, shared-core "burstable" machine — the kind that idles cheaply and borrows extra CPU only when it briefly needs it — cut the compute cost roughly in half. It even came with more memory than before.

The habit worth building: size machines to what they actually do, measured, not to what you once imagined they might need. A minute with a load monitor is worth more than an hour of guessing.

The quiet extras: region, disk, IPs and logs

Once the big items were handled, a set of small ones were each worth a few dollars, and together a meaningful slice.

Region. The exact same machine costs noticeably more in some regions than others — a premium of 30 to 40% is common for the more expensive locations. That premium is often worth paying: keeping a database close to your users cuts latency, and moving a production system across the world is risky. But pick your region on purpose, knowing what the proximity costs, rather than out of habit.

Disk tier. Fast SSD disks cost roughly double a "balanced" disk of the same size. A small database that is mostly idle does not need premium disk performance. Matching the disk tier to the actual workload is an easy, invisible saving.

Idle IP addresses. Reserved static IP addresses are billed even when they are attached to nothing. We found one reserved address doing absolutely nothing and released it. Worth a scan.

Logs. Log ingestion is free up to a generous monthly allowance, then billed per gigabyte. One noisy service — including a bug that threw the same error thousands of times a day — was pushing us over the line. We added a filter to drop the low-value noise (while keeping real errors) and flagged the bug to fix at the source. Verbose logging is a cost, not just a habit.

About those "commit and save" discounts

Cloud providers offer real discounts if you commit to a resource for one or three years. They can be worth it for a steady, permanent workload. But read the fine print: the cheap shared-core machines are often not eligible, and — importantly — right-sizing first can beat committing. In our case, downsizing an idle machine saved more than a one-year commitment on the oversized one would have. Do the cheap, reversible optimisation before you sign a year-long contract.

The takeaway

None of this was clever. We did not rewrite anything or adopt a new platform. We read the bill like a map, found the one workload that was most of it, and turned the right dials:

Move
Why it worked
Group the bill by cause
One workload was 60% of it; the rest was noise
Mind Cloud Run min-instances and CPU
Warm instances and always-on CPU bill 24/7
Self-host the chatty database
Per-operation pricing punishes high-volume writes
Right-size idle machines
A 0.00 load average is money burning
Sweep the small stuff
Region, disk tier, idle IPs and noisy logs add up

Cloud platforms are a wall of dials, and the defaults are tuned for convenience and for the provider's revenue — not for your bill. The good news is that the same wall of dials is exactly what lets you fix it. Set a reminder to audit the bill every quarter. The cloud rewards attention, and quietly taxes the lack of it.

If you run anything in the cloud and have never grouped your bill by cause, that is the single most valuable hour you can spend this month.

Comments (0)

Leave a Comment
Your email won't be published. We'll only use it to notify you of replies to your comment.
Loading comments...
Previous Article
post-thumb

Oct 03, 2021

Setting up Ingress for a Web Service in a Kubernetes Cluster with NGINX Ingress Controller

A simple tutorial that helps configure ingress for a web service inside a kubernetes cluster using NGINX Ingress Controller

Next Article
post-thumb

Aug 30, 2026

The AI Tax Workflow Needs an Audit Trail

AI can make self-managed tax returns easier, but every suggestion needs a traceable record of its source, assumptions and final decision.

agico

We transform visions into reality. We specializes in crafting digital experiences that captivate, engage, and innovate. With a fusion of creativity and expertise, we bring your ideas to life, one pixel at a time. Let's build the future together.

Copyright ©  2026  TYO Lab · v0.0.27