← All articles
An open book unfolding into a row of reading seats beside a small cardboard box
Original illustration created for The Harithsa Notes.
AI & building

From Five Readers to Twenty-Five

Part 2 of my cloud bill story. More readers, smaller Hosting and Firestore readings, and a few things I still need to measure.

The last time I wrote about my website, I had five readers and a cloud bill close to ₹1,000. I moved the artwork out of the deployment package, trimmed what I kept in Hosting, and let the browser choose smaller images when it could. Then I went back to see what changed.

The active-user count I was watching went from 5 to 25. Twenty-five is still a small room. I was happy to see more people in it. I was just as curious about how much work the website was doing behind the scenes.

My dear cousin read Part 1 and told me there was too much text. I’d written about what I saw in the Firebase console, but I’d made readers do a lot of the work of picturing it. His feedback pushed me to get better at telling the story visually. This time I wanted to show you the actual screens, walk through a real example, and let Xiaohei have a little fun with the parts I’d usually explain in another paragraph.

Part 1: Know Your Cloud Cost per User Before You Build

A quick map of the site

Xiaohei delivers a page at a Hosting counter, with a Functions press, a Firestore drawer, and a separate Storage rack for artwork.
Xiaohei hands you the page. When the browser needs the artwork, it fetches it from its own shelf.
  • Hosting is the front door. It serves the site’s static files and routes requests that need application code.
  • Functions runs the server code for those requests. At launch I ran that code on a Cloud Run service I deployed directly.
  • Firestore stores the site’s content and app records. It meters reads and writes separately.
  • Cloud Storage for Firebase holds the media. I moved the public illustrations there so they could be served separately from the Hosting release.

What I changed · What the bill showed · Storage and downloads · Reads, writes, and Functions · Before and after · Cost per active user

What I changed

  1. I separated the artwork from the release. Public images now live in Cloud Storage for Firebase, with smaller renditions for smaller screens. For the bucket type and eligible region I use, Firebase lists up to 5 GB-months of storage and 100 GB of downloads per month at no cost, subject to eligibility and transfer rules. Firestore has its own 1 GiB of stored data and 10 GiB per month of network egress allowance. Firebase pricing · Cloud Storage usage limits
  2. I cleared out old deployment baggage. I removed obsolete build inputs and Hosting versions and kept recovery material locally. I wanted a small rollback window, with the last three releases as my target. During the cleanup, the live Hosting channel held the current release and I kept a local rollback copy. That let me separate what I needed to recover from what I needed to pay to store online.
  3. I changed how I built and ran the server. I first used Docker to build the server image, pushed it to Docker Hub, and deployed that image to Cloud Run. I then moved the production server behind a second-generation Firebase HTTP Function. Firebase builds and stores the image for that function and runs it on managed Cloud Run. For a Hosting-only update I can pin the function revision I already have, so changing the Hosting files doesn’t trigger another function build. How Google builds and deploys functions
Xiaohei makes room for more readers while swapping an oversized deployment box for a small one.
More room on the bench. Less to carry every time I change a sentence.

The bill I came back to

Firebase project cost summary showing a total of ₹952.85, including ₹615.62 in Non-Firebase Services and ₹293.31 in Hosting.
The cost snapshot totals ₹952.85. Non-Firebase Services (₹615.62) and Hosting (₹293.31) account for about 95% of that total.

Those two lines were where I’d look first. The cost chart records charges that had already accumulated. I went to the usage panels to see what the site was doing after the changes.

What I kept and what I sent

Firebase Hosting storage chart with a large earlier bar and a November 10 tooltip of 2.4 MB.
Hosting storage showed 2.4 MB on November 10, compared with the 22.7 GB I saw in Part 1. Both are project storage readings. The 660.83 MB and 1.24 MB figures from Part 1 compare individual releases.
Firebase Hosting downloads chart with earlier spikes and a November 9 tooltip of 156 MB, within the displayed no-cost tier.
Hosting downloads showed 156 MB for November 9 at capture, within the 360 MB/day threshold displayed by the console. The 20.5 GB paid-tier figure summarizes a different window.

I’d moved some of the delivery work to Cloud Storage, so I opened that dashboard too. One panel tells me what I’m keeping. The other tells me what I’m sending.

Cloud Storage across all buckets showing 409.4 MB in the November 10 tooltip.
Cloud Storage’s selected November 10 point was 409.4 MB across all buckets. The 404.7 MB summary is a separate reading on the same screen.
Cloud Storage bandwidth across all buckets with 33.8 MB for November 8 and 17.5 GB since the start of the month.
The bandwidth tooltip shows 33.8 MB for November 8 and 17.5 GB since the start of the month. To compare transfer across Hosting and Storage, I’d pull the same days from both.

A reader is one person. Firestore has other ideas.

Xiaohei presses a stamp once and scrambles to catch a long chain of receipts, showing one visit can involve multiple operations.
The reader opened one page. Xiaohei would like to file a separate report about everything that happened next.
Cloud Firestore reads with early bars around 125,000 and 150,000 and a latest captured reading of 47,000.
Reads peaked near 150,000 on the chart. The later panel showed 47,000 so far, close to the displayed 50,000/day no-cost threshold.
Cloud Firestore writes with early bars near 75,000 to 80,000 and a latest captured reading of about 14,000.
The early write bars were around 75,000–80,000. The later panel showed about 14,000 so far, against the displayed 20,000/day threshold. The latest readings can still move before the day ends.

The bars were smaller even as the audience grew. That made me want to trace one ordinary visit and check how many reads it creates. I’d look at writes separately and check which ones come from scheduled work or publishing. Those jobs can run even when the reading room is empty.

Firebase Functions showing about 6,100 month-to-date invocations within the displayed no-cost invocation quota.
Functions recorded about 6,100 invocations month to date, roughly 0.3% of the displayed invocation quota. The cost snapshot separately shows ₹12.64 for Cloud Functions. I’d check the billing breakdown to see which usage was charged.

Before and after

What I was watching Early reading Follow-up reading
Active users 5 25
Hosting storage across the project 22.7 GB in Part 1 2.4 MB on November 10
Hosting downloads Multiple GB on the early spike days 156 MB for November 9 at capture
Firestore reads Early daily bar peaked near 150,000 47,000 so far on the captured day
Firestore writes Early daily bars reached roughly 75,000–80,000 About 14,000 so far on the captured day

This is what I saw when I went back to the dashboards. The Firestore comparisons put early daily bars next to readings that were still in progress. For a savings calculation, I’d pull complete periods and use the same scope on both sides.

Cost per active user

Xiaohei clips the cost and active-user slips together under a bracket marked Same dates.
The most useful piece of equipment in my DevFinOps practice might be a binder clip.

Estimated cloud cost per active user = cloud costs allocated to the app for the period ÷ distinct active users of the app in that same period

I’d start with a complete week or month, count each person once, and use the same definition of an active user in both windows. I’d keep one-off build or migration costs visible so I could explain a change in the average.

That’s the DevFinOps conversation I want to have. When someone asks how much it costs to serve the next twenty-five people, I want to be able to show my work.

Illustrations use the Ian Xiaohei Illustrations workflow.

Back to all articles ↗

Search the notebook

A THOUGHT, A BOOK, A LITTLE CURIOSITY

Where shall we start?

Search across the notebook.

Search the published notebook.