← All posts

Three kinds of storage first — then Cloudflare vs Firebase

When you’re building an indie app or Android product, the sticky question usually isn’t “Is Cloudflare better than Firebase?” It’s a simpler one: where should this thing live?

Files, user records, and a marketing site all sound like “storage.” Under the hood they’re three different shelves. Brand names are just labels on those shelves. Separate the shelves first, then pick a vendor.

Cover diagram: files, records, and websites as three kinds of storage
Files, records, websites — three different shelves.

Three “stores” that are not the same thing

A WeChat-style analogy helps:

Three columns: object storage, database, and hosting, with Cloudflare and Firebase labels
Same word “store.” Three different shelves.
Everyday nameWhat you keepFeels like…CloudflareFirebase
Place for files (object storage)Images, video, PDFsPhotos/videos in chatR2Storage
Place for records (database)Names, orders, text fieldsFriend list / message rowsD1 / KVFirestore / RTDB
Place for the site shell (static hosting)HTML / CSS / JSMini-program shell / landing pagePagesHosting

In short:

  • Object storage: fetch a whole file by key — like a drive.
  • Database: query rows by conditions — like an address book.
  • Hosting: open a URL and get a page — like a CDN-backed site.

A full app often needs all three. Don’t use a photo bucket as a user table, and don’t expect static hosting to be your album.

Static sites: compare Pages with Hosting — not Workers

People often compare Workers (run code at the edge) with Firebase Hosting (static hosting). That’s the wrong shelf.

  • Hosting / Pages: push site files to the edge so people can open a URL.
  • Workers: run your logic (APIs, auth checks, assembled responses). Not the shelf for “put the homepage here.”

So for a static site, compare Firebase Hosting vs Cloudflare Pages. For APIs / backend logic, look at Workers (on Firebase you often add Cloud Functions).

Cloudflare Pages versus Firebase Hosting on Spark: unlimited traffic per notes versus about 360 MB per day
Hosting pairs with Pages — not Workers.

On free tiers, Pages is usually wider

Cloudflare PagesFirebase Hosting (Spark)
StorageNotes say unlimited~10 GB
TrafficNotes say unlimited~360 MB/day (then metered)
Free subdomain*.pages.dev*.web.app

No slogans needed: for a landing page, docs site, or simple marketing site, Pages free traffic looked wider. If you’re already deep in Firebase (auth + Firestore), Hosting is still convenient — just watch the ~360 MB/day line.

Workers free tier has its own request limits (notes often cite ~100k/day). That’s a “running code” bill — don’t mix it with static traffic.

Photos: R2 and Firebase Storage don’t share the same on-ramp

Avatars, galleries, attachments — that’s object storage.

From the notes (2026-08; Storage policy from then-current firebase.google.com/pricing):

Cloudflare R2Firebase Storage
Usable on free tier?Yes; notes cite ~10 GB storage, egress-friendly free tier, monthly op limitsSpark marks Storage Not applicable
To use itSign up and stay within free quotasNeed Blaze (pay-as-you-go) + a card; Blaze has its own free allowances, but “zero-card free start” is gone

For indies this often matters before SDK taste: Storage isn’t available on Spark; R2 can get “store images” working inside a free tier.

Exact Blaze free GB/ops: use today’s pricing page. Example traffic math in the notes is hypothetical — not your real bill.

Login and storage are two jobs

“Users sign in with Google, so everything must live on Firebase” is a common mix-up.

  • Login (Google Sign-In): proves who you are and gives a verifiable ID token.
  • Storage: images and user tables can live on Cloudflare (R2 / D1) or elsewhere.
Flow: Android app signs in with Google, a Worker verifies the token, then R2 stores images and D1 stores records
Login proves who you are. Storage can live elsewhere.

A workable pattern:

  1. App signs in with Google and gets an ID token
  2. Send the token to a Cloudflare Worker
  3. Worker verifies the token with Google
  4. On success, read/write R2 (files) or D1 (structured data)

One line: Auth can be Google; the warehouse can be Cloudflare. They don’t fight.

In similar indie Android / app setups, people often split “login here, storage there” when counting cost — instead of defaulting to one full vendor stack.

A common indie stack

If the goal is roughly: Android app + Google login + user uploads + a bit of structured data, the notes keep landing on:

NeedCommon pick
Prove identityGoogle Sign-In (auth can start free)
Backend APICloudflare Workers
Images / filesCloudflare R2
User / business rowsCloudflare D1 (SQL); cache/session via KV
Site / landingCloudflare Pages

Be honest on cost: within free quotas and without heavy AI burn, you can often start near-free besides the domain. Domains you usually still buy. Quotas change and projects grow — don’t write “forever free.”

Quotas are usually shared per account

Cloudflare free quotas are mostly one pool per account, not a fresh full allotment per project:

  • Multiple Workers share daily request limits
  • Multiple R2 buckets share storage + ops
  • Multiple D1 databases share total storage (instance caps too)

Pages traffic looked relatively generous per project in the notes; build counts and other limits may still be account-wide. Opening another side project doesn’t always mean “another full free package.”

Quick lookup

You need…Look at firstNotes
Static site, fear blowing free trafficCloudflare PagesPairs with Hosting, not Workers
Already deep in FirebaseFirebase Hosting + ecosystemEasy integration; watch daily Hosting traffic
User uploads, want a free-tier startCloudflare R2Storage unavailable on Spark (per notes)
Structured user / business dataD1 or FirestoreRealtime needs change the taste
Realtime sync / listenersFirestore / RTDBNot the same model on CF
Edge API, light logicWorkersDon’t treat as a static-hosting substitute
Google login + low-cost files + tablesSign-In + Workers + R2 + D1Split auth and storage

Close

Ask three questions:

  1. Am I storing files, records, or a website?
  2. Am I comparing hosting or running code?
  3. On the free tier, can I turn this on, or do I need a card?

Once the three shelves are clear, Cloudflare vs Firebase stops being tribal — it’s shelf matching.

(If you’re also splitting storage for an indie app, run the math on your own traffic and uploads — more useful than arguing brands.)