Firebase Hosting Cost, Measured Against a Real 156 MB Build
Firebase bills $0.026/GB stored and $0.15/GB transferred. This storefront's 156.5 MB build uses 1.6% of the free storage tier — transfer is the line that bills.
Most Firebase Hosting cost articles quote the price list and stop. The price list is two numbers; the useful question is what your build actually weighs against them. This storefront's production build is 156.5 MB of deployable files — 340 prerendered HTML pages, 1.5 MB of JavaScript chunks and 96.3 MB of images — so the arithmetic below runs on measured bytes rather than a hypothetical site.
The short answer
Firebase Hosting is free until you cross 10 GB of stored files or 10 GB of monthly transfer, then bills $0.026 per extra GB stored and $0.15 per extra GB transferred. Storage almost never costs anything: this 156.5 MB build uses 1.6% of the free tier. Transfer is the line that bills, and images, not HTML, drive it.
What Firebase Hosting charges
| Spark (free) | Blaze (pay as you go) | |
|---|---|---|
| Stored files | 10 GB | 10 GB free, then $0.026/GB |
| Data transfer | 10 GB/month | 10 GB/month free, then $0.15/GB |
| Daily egress ceiling | 360 MB/day | none |
| Custom domain + SSL | included | included |
| Serverless compute | none | not part of Hosting — see App Hosting below |
Two things about that table matter more than the numbers. First, the free tier is per-project, not per-site. Second, Hosting bills stored files and transferred bytes only — it runs no code. That second point decides whether the price list applies to your app at all, and it is the section most comparisons skip.
What a real build weighs
Counted from .next/ and public/ after npm run build on this repository, not estimated:
| Part of the deploy | Size | What it is |
|---|---|---|
| Prerendered HTML | 66.3 MB across 340 files | 111 product pages, 207 blog posts, 7 category hubs, the static routes |
| JavaScript + CSS chunks | 1.5 MB | .next/static/chunks, the whole client bundle for every route |
public/ | 96.3 MB | 683 WebP derivatives, 446 JPEGs, brand art |
| Total deployable | 156.5 MB | 1.6% of the 10 GB free storage tier |
At $0.026/GB, storing all of it costs $0.004/month — and since it sits inside the free 10 GB, the actual storage bill is zero. You would need to ship this catalog 60 times over before Firebase charged a cent for storage. If you are budgeting for Firebase Hosting, storage is not the line to model.
The 58.7 MB nobody ever downloads
446 of those JPEGs total 58.7 MB, and no page renders a single one. They are the SEO copies: screenshots[0] is the cover that og:image and the Product schema resolve to, plus its 1:1 / 4:3 / 16:9 crops. Every on-page <img> points at a pre-built WebP derivative instead, resolved by cardImage() and viewImage() in src/lib/imageVariants.ts and generated by scripts/images/build-variants.ts:
const RASTER = /\.(?:jpe?g|png|webp)$/i;
function variant(src: string, suffix: string): string {
return RASTER.test(src) ? src.replace(RASTER, `-${suffix}.webp`) : src;
}
/** Card-sized cover — product grids, the related rail, dashboard thumbnails. */
export function cardImage(src: string): string {
return variant(src, "card");
}
The 110 card derivatives average 32 KB and the 110 detail-frame derivatives average 42 KB, against 135 KB for the average JPEG they were built from. That split is the whole reason this build's cost profile works: 58.7 MB of it is stored (nearly free) and almost never transferred (the expensive one), because a crawler fetching an og:image is a handful of requests a month, not a page view.
Where the bill actually comes from
Firebase serves HTML compressed. Uncompressed page weight is the wrong number to budget with, so here is both, measured with gzip -9 on this build's output:
| Page | HTML on disk | HTML gzipped |
|---|---|---|
/blog | 1,381 KB | 139 KB |
/ | 425 KB | 85 KB |
/templates | 474 KB | 33 KB |
/pricing | 173 KB | 34 KB |
| a product page | 149 KB | 27 KB |
A 10–14× compression ratio is typical of prerendered React output, which is repetitive by construction. /blog is the outlier at 139 KB because it renders all 207 post cards in one grid; /templates compresses harder despite being larger on disk because 111 near-identical card markup blocks is exactly what a dictionary compressor is good at.
Now the part that does not compress. A /templates view pulls the grid's cover art, and WebP is already compressed — 110 cards at 32 KB is 3.5 MB if every card loads. The HTML is 33 KB of that request; the images are a hundred times more. This is why the first card of a page-opening grid is the only one marked priority in TemplatesExplorer and every other card stays loading="lazy": lazy loading is a performance decision that happens to also be the transfer-cost decision.
Rough monthly arithmetic at a realistic ~500 KB per page view, images included:
- 10 GB free transfer ÷ 500 KB ≈ 20,000 page views/month at no cost
- 100,000 page views ≈ 50 GB ≈ 40 GB billable ≈ $6.00/month
- 1,000,000 page views ≈ 500 GB ≈ 490 GB billable ≈ $73.50/month
On the Spark plan the 360 MB/day egress ceiling binds first: roughly 720 page views a day at that weight, after which the site stops serving until the window resets. That ceiling, not the price, is why most projects that outgrow a prototype move to Blaze.
The catch that decides whether any of this applies
Firebase Hosting serves static files. It does not run your server code. This storefront cannot deploy to Hosting alone, and the reason is countable:
src/proxy.ts # runs ahead of nearly every request
src/app/api/download/route.ts # gated download
src/app/api/webhooks/lemonsqueezy/route.ts # signed webhook
src/app/auth/callback/route.ts # OAuth code exchange
src/app/blog/feed.xml/route.ts # RSS
src/lib/actions/account.ts
src/lib/actions/auth.ts
src/lib/actions/checkout.ts
src/lib/actions/contact.ts
src/lib/actions/entitlementsView.ts
src/lib/actions/newsletter.ts
src/lib/actions/redemption.ts
src/lib/actions/refund.ts
One Edge proxy, four Route Handlers and eight Server Action modules. A checkout, a signed webhook and a gated download are not files you can put in a bucket. On Firebase that work moves to App Hosting (Cloud Run underneath) or to Cloud Functions, and the pricing model changes shape entirely — from bytes stored and transferred to vCPU-seconds, memory-seconds and requests, with a Cloud Build charge per deploy.
| Firebase Hosting | Firebase App Hosting | Vercel (what this site runs on) | |
|---|---|---|---|
| What it runs | static files only | a Next.js server on Cloud Run | a Next.js server + Edge middleware |
| Billing unit | GB stored, GB transferred | vCPU-s, memory-s, requests, egress, build minutes | usage-based compute + bandwidth |
| Free tier | 10 GB storage, 10 GB/mo transfer | Cloud Run free tier, then metered | Hobby tier, Pro from $20/mo |
| Fits this app | no — 13 server files | yes | yes |
| Fits a marketing site | yes | overkill | yes |
If your Next.js app is a pure static export — output: "export", no Route Handlers, no Server Actions, no middleware — Firebase Hosting's price list is the whole bill and it is an excellent deal. The moment one server file appears, you are pricing App Hosting, and "firebase hosting cost" stops being the question you are actually asking. Vercel vs. Firebase works through that same boundary from the architecture side, counting what Cloud Functions would have to replace.
Cutting the transfer bill
Everything below is what this repository actually does, in the order it pays off:
- Serve derivatives, not originals. 32 KB WebP instead of 135 KB JPEG is a 4× cut on the bytes that dominate every page view. Build them once at deploy time —
npx tsx scripts/images/build-variants.ts— so there is no request-time optimizer to pay for either. - Lazy-load everything below the fold. One
priorityimage per page, the rest lazy. On a 111-card grid that is the difference between 3.5 MB and whatever the visitor actually scrolls to. - Let the CDN cache. Firebase Hosting's CDN serves a cached file without re-billing transfer from origin; long
Cache-Controlmax-ages on hashed asset paths are free money. - Do not store what you do not serve. Storage is cheap enough to ignore, but 58.7 MB of unused crops is 58.7 MB you re-upload on every deploy, which is deploy time rather than dollars.
Worth noting that Hosting is rarely the whole Firebase bill either. Firestore bills per document read, and a client-first app makes a great many of them — Firebase vs. Postgres works through what that query path actually looks like against a server-fetched alternative, which is the same decision seen from the data side.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Bill appears despite "free tier" | Blaze bills per-project; another Firebase service (Firestore reads, Cloud Functions invocations) crossed its own free tier | Read the per-service breakdown in the billing console, not the total |
| Site stops serving mid-day on Spark | The 360 MB/day egress ceiling, not the 10 GB/month one | Upgrade to Blaze, or cut per-view weight — images first |
| Transfer far higher than page views × HTML size | Images and fonts are not compressible and dwarf the HTML | Measure a real page view in DevTools' Network tab, not the HTML file size |
| Deploy fails on file count | Hosting caps files per deploy (and per version) | Prune generated crops and old build output before firebase deploy |
Next.js app 404s on every route but / | Static-file hosting cannot run the server routes the app needs | Deploy to App Hosting, or convert to a true static export |
Frequently asked questions
Is Firebase Hosting free? Yes, up to 10 GB of stored files and 10 GB of monthly transfer, with a 360 MB/day egress ceiling on the Spark plan. A 156.5 MB build like this one uses 1.6% of the storage allowance, so the transfer side is the only one worth modelling.
How much does Firebase Hosting cost for a small site? For most marketing sites and portfolios: nothing. Crossing 10 GB of transfer takes roughly 20,000 page views a month at 500 KB per view, and the first GB past that is $0.15. A site at 100,000 monthly views lands near $6/month.
Does Firebase Hosting cost more than Vercel or Netlify? Per GB transferred, Firebase's $0.15 is in the same range as its competitors' overage rates. The difference is what happens when you need server code: Hosting can't run it at all, so the comparison becomes App Hosting's compute pricing versus Vercel's — a different model, not a different rate.
Why is my Firebase Hosting bill mostly transfer and not storage? Because storage is billed once per stored byte and transfer is billed every time a visitor downloads one. 96.3 MB of images stored costs $0.0025/month; the same images served to 20,000 visitors is 10 GB.
Templates in this post
ASoc Beacon, ASoc Beaker and ASoc Blueprint are Next.js + Tailwind landing page templates built the way this cost analysis recommends — prebuilt WebP derivatives, one priority image per page, and no request-time image optimizer to pay for.
Browse the full sets: Next.js landing page templates, Tailwind landing page templates.
