DevTeardown
English

English comparison articles · 비교글 영어 원문 · 比较文章为英文 · 比較記事は英語 · Artículos en inglés · Articles en anglais

Backend & Database Supabase vs Firebase Source review recorded 2026-11-10 · 5 min read

Supabase vs Firebase

Fifty users watching a hundred documents that change twenty times a minute cost about $1,296 a month in Firestore reads, and a flat $25 on one Supabase Pro Micro project. The screen is identical; the only thing that changed is what the vendor counts.

Verdict

If your bill grows with how often people watch data rather than how much data you keep, Supabase wins: that dashboard is about $1,296/month of Firestore reads against $25 for one Pro Micro project. If your app fits Firestore's daily free quota of 50,000 reads, 20,000 writes and 20,000 deletes, stay where you are, because leaving costs a schema project and a password path the migration repo still marks incomplete.

In this teardown
  1. The billing unit decides what code you may write
  2. A listener is a meter, not a subscription
  3. On Supabase the ceiling is capacity, not a per-read meter
  4. Index entry reads are the Firestore line item nobody quotes
  5. Migration is a schema project with a script attached
  6. Pick by bill shape first, then by blockers
  7. Cost arithmetic
  8. Decision matrix
  9. Migration path
  10. FAQ

At a glance

Dimension Supabase Open source Firebase Managed Google
Product foundationPostgreSQL (relational + pgvector)Firestore (NoSQL document store)
Pricing modelFree: 500 MB, 2 projects · Pro $25 + $10/project computeDaily free quota · reads $0.03 / writes $0.09 per 100k
Hosting and deploymentYes (Docker stack)No (proprietary GCP)
Runtime and integrationPostgres Changes (CDC, row-level-security aware)Snapshot listeners — a read per changed document
AI-related capabilitiespgvector in the same database as your app datakNN vector search, billed per 100-entry index batch
Lock-in riskLow: standard Postgres, dump and leaveHigh: rules, SDKs, and no SQL export path
Vendor Supabase → Firebase →

1. The billing unit decides what code you may write

Supabase sells a machine. You rent a Postgres instance, a disk and a connection ceiling, and reads inside them are free. Firebase sells events. Every document read, write, index batch and listener update is a line on the invoice, with a daily free quota on top.

What each philosophy forbids:

MeterUnit pricePattern it punishes
Firestore reads$0.03 / 100,000Live listeners on hot documents
Firestore writes$0.09 / 100,000Per-keystroke saves, chatty counters
Supabase disk$0.125/GB over 8 GBKeeping everything forever
Supabase compute$10 to $3,730/month per projectMany connections, many projects

2. A listener is a meter, not a subscription

A listener is not a free subscription. Firestore bills a read each time a document enters or updates in a live listener's result set, and one more when a change pushes it out. The meter runs while nobody clicks. Don't pick Firestore for a screen that stays open all day.

Take 50 users, each watching 100 documents that change 20 times a minute:

users, docs, changes_per_min = 50, 100, 20
reads = users * docs * changes_per_min * 60 * 24 * 30
print(reads)                   # 4.32B events, zero clicks
print(reads / 100_000 * 0.03)  # 43,200 x $0.03, before free quota

That is a gross read charge at the us-central1 rate, before free-quota adjustments. One Pro Micro project costs $25/month inside its quotas — which says nothing about whether that instance can carry the load, only that the bill stops tracking the watching. Reconnects make it worse:

3. On Supabase the ceiling is capacity, not a per-read meter

Postgres Changes is a database event stream, and you opt in per table:

Add a table to the publication: alter publication supabase_realtime add table your_table_name;

Nothing in that stream is metered per read. What runs out is the instance: its compute tier and its connection and pooler limits. Compute is billed per project, separately from the plan.

ComputeMonthly computeDirect / pooled database connections
Micro$1060 / 200
Small$1590 / 400
Medium$60120 / 600
Large$110160 / 800
XL$210240 / 1,000
16XL$3,730500 / 12,000

You stop paying for spikes and start paying for headroom. Size for peak connections: Pro's $10/month credit covers one Micro, and every extra project adds its own compute.

4. Index entry reads are the Firestore line item nobody quotes

Firestore's own docs give the example: count() over 1,500 index entries bills 2 document reads.

Ten million plain reads cost $3.00 at the listed rate. The count() in your page header is a different bill.

Audit any query that combines two range fields before it ships.

5. Migration is a schema project with a script attached

supabase-community/firebase-to-supabase on GitHub is community tooling, not an official CLI. What it does:

  1. firestore2json.js exports a collection; json2supabase.js loads it into a table. One collection, one table.
  2. Fields are flattened to text, numeric, boolean or jsonb.
  3. Splitting nested JSON into related tables needs custom hooks you write.

Auth is the sharper edge. firestoreusers2json and import_users move users, importing hashes with Firestore's SCRYPT parameters (base64_signer_key, base64_salt_separator, rounds, mem_cost).

Verifying an existing Firebase password on first login needs a middleware the repo itself marks work in progress. The AWS Lambda variant is listed as TBD.

Until that middleware exists, plan for blocked logins at cutover and decide in advance whether you force a password reset.

6. Pick by bill shape first, then by blockers

Choose Supabase when modeled Firestore charges exceed the plan and compute cost and the workload fits the selected tier and quotas. Keep Firestore when all free allowances fit:

Check today, in this order:

  1. Multiply listeners × documents per listener × changes per minute × (60 × 24 × 30) minutes, then × $0.03 per 100,000.
  2. Find every hot-path query with two range fields or a count().
  3. On Supabase, compare peak database connections to Micro's 60 direct / 200 pooled.
  4. Check whether first-login existing-password verification blocks migration.

Cost arithmetic at volume

These are computed from the published unit prices, not measured. Each row prints its own formula, so you can replace our assumption with your traffic and redo it.

Firestore: hypothetical continuous dashboard, 50 users watching 100 documents each changing 20 times/minute
50 × 100 × 20 × 60 × 24 × 30 = 4.32 billion read events/month; 4.32 billion ÷ 100,000 = 43,200 batches; 43,200 × $0.03 = $1,296
≈ $1,296/month
Supabase Pro: one Micro project, subject to capacity and included quotas
$25 (plan) + $10 (Micro) − $10 (included compute credits)
$25/month for one Pro Micro project within included quotas; egress beyond 250 GB costs $0.09/GB
Supabase's official billing example: Pro org, 2 Micro projects
$25 (plan) + $10 (project 1) + $10 (project 2) − $10 (credits)
$35/month within included quotas
Firestore: 10 million plain document reads
10,000,000 reads ÷ 100,000 reads/batch = 100 batches; 100 × $0.03 = $3.00
$3.00 at the listed read rate, before allowances

Decision matrix

Rows are the situation you are actually in. Pick the row before you read the pricing page again.

If this is youTakeBecause
Live dashboard whose modeled Firestore charges exceed Supabase costs, within the selected tier and quotasSupabaseOne Pro Micro project costs $25/month within included quotas after the compute credit; listener updates count as Firestore reads. Check capacity separately.
Quiet app within every relevant Firestore free allowanceFirestoreStay when reads, writes, deletes, stored data and outbound transfer all fit: 50,000 reads, 20,000 writes and 20,000 deletes daily, 1 GiB stored, 10 GiB/month outbound and one free database per project.
Relational reporting requiring JOINs, with migration schema work acceptedSupabaseFirestore has no JOINs. Supabase supports SQL JOINs; splitting nested JSON into related tables during migration requires custom hooks.
Offline app whose Firestore usage and reconnect charges fit its budgetFirestore with offline persistence onWith persistence off, every Firestore reconnect is billed like a brand-new query. With it on, disconnections longer than 30 minutes trigger that billing.
Database connection demand fits 16XL and its cost fits the budgetSupabase16XL offers 500 direct / 12,000 pooled database connections at $3,730/month compute, separately from the plan; larger sizes are available by request.
Agency whose verified total Firestore usage charges are lower than the Supabase setupFirestoreCompare client workloads against the $35/month Pro total for 2 Micro projects within included quotas. Every extra Supabase project adds its own compute line, $10 for each Micro.
Existing Firebase password verification at first login is required, but its migration dependency is unresolvedStay on FirebaseFirst-login verification of Firebase passwords depends on middleware the migration repo marks work in progress.
Aggregate-call charges remain below the Supabase setup costFirestoreFirestore's count() bills index reads on every call, with a 1-document-read minimum. A count over 1,500 index entries bills 2 document reads; compare call volume at $0.03 per 100,000 reads against $25/month for one Supabase Pro Micro project within included quotas.

Code and configuration

Supabase
// Relational read in one round trip. Free-tier note:
// the nested select is a JOIN, so 50 comments cost 0 extra reads.
const { data, error } = await supabase
  .from('posts')
  .select('id, title, comments(id, body, user_id)')
  .eq('published', true)
  .order('created_at', { ascending: false })
  .limit(20);
// Here it breaks: anon key + missing RLS policy = empty array, not an error.
if (error) throw error;
Firebase
// N+1 by design: comments are a second query per post.
const q = query(collection(db, 'posts'), where('published', '==', true));
const snap = await getDocs(q);           // 20 reads
for (const doc of snap.docs) {
  // Denormalise, or pay: 20 more queries = 20 more billed reads
  const comments = await getDocs(collection(doc.ref, 'comments'));
}
// Here it breaks: a live listener on this collection bills a read on
// every document update, for every listener, for as long as the tab is open.

What you gain, what you give up

Supabase

You gain
  • One invoice for compute, disk and connections — reads inside the instance are not metered
  • pgvector lives in the same Postgres as your rows, so RAG needs no second system
  • Standard Postgres: SQL, JOINs, transactions, triggers, and pg_dump as an exit door
  • The connection ceiling is purchasable: 200 pooled connections on $10 Micro up to 12,000 on $3,730
You give up
  • You buy headroom, not usage: peak connections decide the tier, and idle capacity still bills
  • Every extra project adds its own compute line ($10 for a Micro) even on one Pro plan
  • Free projects are paused after a week of inactivity, which kills demo and staging projects
  • Realtime subscriber capacity is not on the price sheet; you size by connection and compute limits

Firebase

You gain
  • Offline persistence and multi-platform SDKs that work when the network does not
  • No connection pool to size: events are metered, not sockets
  • A daily free quota of 50,000 reads and 20,000 writes per project
  • Listeners bill only for documents that change in the result set, not for every poll
You give up
  • A dashboard left open all day is a recurring read charge: 50 users can pass $1,296/month
  • Reconnects are billed like brand-new queries — with persistence off, every one of them
  • Index entry reads are a second meter: a second range field starts billing
  • No JOIN, and the export tool flattens one collection to one table, so schema design lands on you

Migration path

What switching actually takes

supabase-community/firebase-to-supabase is community tooling, not an official CLI. firestore2json.js exports one collection, json2supabase.js loads it into one table, and fields are flattened to text, numeric, boolean or jsonb — splitting nested JSON into related tables is a hook you write. Auth is the harder half: firestoreusers2json and import_users carry passwords over as SCRYPT hash parameters, and verifying a user's existing Firebase password on first login needs middleware the repo still marks work in progress. Budget the schema work, not the script.

Common questions

Can I park a Supabase Free project for a demo that sits idle?
Not reliably: Free projects are paused after 1 week of inactivity, and Free allows only 2 active projects. Pro projects are never paused for inactivity.
Does offset pagination save reads on Firestore?
No. Firestore bills a read for every skipped document, so offset 10 returning 1 document costs 11 reads.
Will Supabase Realtime leak rows a user shouldn't see?
Postgres Changes subscriptions are RLS-aware, so clients receive only rows they are allowed to select. Supabase's docs also document Broadcast as an alternative way to subscribe to database changes.
How is Firestore vector search billed?
kNN vector search bills one read per batch of up to 100 vector index entries. That is a tenth of the 1,000-entry batch size used for regular index entry reads.

Sources & verification

Prices and limits were read from these pages on 2026-11-10. Vendor marketing claims are quoted as claims. Anything derived is arithmetic on the numbers below.

https://supabase.com/pricing
https://supabase.com/docs/guides/realtime/postgres-changes
https://firebase.google.com/docs/firestore/pricing
https://cloud.google.com/firestore/pricing
https://supabase.com/kb/guides/migrate-from-firestore-data

Keep reading

Vercel vs Cloudflare Pages

The same penalty-table reading, applied to hosting: which line your workload inflates.

Notion vs Obsidian

Another free tier that is really a history and API budget.

Try Supabase → Explore Firebase →
Source review date recorded in this article: 2026-11-10. This is not a live price or checkout check. Prices can change. If a number here looks wrong, the vendor's own price sheet wins. Derived figures are arithmetic on published unit prices, not measured benchmarks.