MongoDB → Supabase
Move MongoDB documents, users, files, queries, and application access into Supabase Postgres, Auth, Storage, and Row Level Security without treating a JSON dump as a finished backend.
Should you make this move?
Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.
MongoDB
- Flexible documents and horizontal scaling suit rapidly evolving application data
- A mature data model and query ecosystem supports serious production workloads
- Relational integrity, joins, and transactional reporting require extra design care
- Schema design, migration, tuning, and operations require specialist attention
Supabase
- PostgreSQL, authentication, storage, realtime, and edge functions offer an open backend stack
- Managed infrastructure removes a large amount of operational work
- Production scaling and service integration still demand database and infrastructure judgment
- Platform-specific services can create architectural lock-in
Supabase: PostgreSQL, authentication, storage, realtime, and edge functions offer an open backend stack. This removes a major source-side concern: Relational integrity, joins, and transactional reporting require extra design care.
What you lose: Flexible documents and horizontal scaling suit rapidly evolving application data. What you inherit: Production scaling and service integration still demand database and infrastructure judgment.
Jump to a section
Know the shape of the move.
This timeline assumes
- Up to 50 collections, 5 million documents, 250,000 users, and 50 GB of files
- Application and data owners approve a versioned target schema, Auth strategy, and RLS policies.
- A production-shaped snapshot and write workload are available for rehearsal.
- MongoDB remains authoritative until lag reaches zero and all invariants pass.
- The migration team records evidence for every blocking verification check.
What survives the move.
“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.
| Item | Outcome | Impact | What happens | Mitigation |
|---|---|---|---|---|
| Documents, nesting, and polymorphism | partial | critical | Supabase’s MongoDB guide loads JSON into a JSONB staging table, then normalizes into relational tables. Collections do not become one-to-one tables automatically. | Design the target schema from production queries before transforming each collection. |
| BSON types and field names | partial | critical | Relaxed JSON can lose type fidelity, and MongoDB documents can contain names that export tools handle poorly. | Use canonical Extended JSON where appropriate and test every BSON type and problematic key. |
| mongoexport as backup | lost | critical | MongoDB explicitly states mongoexport is not a database backup tool. | Create a native restorable MongoDB backup in addition to logical transformation exports. |
| Users and password hashes | partial | critical | Auth.users is strict. Empty strings, missing fields, and duplicate emails can fail an import. bcrypt hashes can keep working when the destination column receives the existing hash. | Map users into the documented Auth shape, load in batches, and test email, social, and password sign-in. |
| Custom user fields and social identities | manual | high | auth.users does not accept arbitrary profile fields. Google and Apple identifiers need provider metadata rather than Mongo field names. | Move profile fields to a related table and rebuild each provider’s sign-in path. |
| MongoDB Data API and application queries | manual | critical | Supabase generates PostgREST from tables. Existing Mongo drivers, Data API calls, and Nest-style repositories do not run unchanged. | Rewrite queries against tables and test every client path before freeze. |
| Row Level Security and validation | manual | critical | Mongo validation and application checks do not become RLS policies. | Translate each access rule into tested policies before client traffic. |
| Indexes, transactions, and change streams | manual | critical | MongoDB runtime behavior must be redesigned in Postgres and application code. | Build constraints and indexes, rewrite queries, and rehearse final change capture. |
| Files, GridFS, and object storage | partial | high | Binary files need a separate copy into Supabase Storage or another object store. | Copy and verify every object and access policy. |
| Identifiers and relationships | partial | critical | ObjectIds often become UUIDs or text keys. Embedded arrays become child tables or JSONB. | Preserve a source ID column and load parents before children. |
| Sessions and in-flight tokens | lost | high | Active Mongo or Nest sessions cannot safely become Supabase sessions. | Plan a reauthentication or token exchange and keep a rollback window. |
| Users, roles, and project permissions | manual | critical | Mongo roles and application admin flags do not become Supabase roles or RLS. | Apply least privilege before application access. |
Where each thing goes.
| Source | Destination | Method | Notes |
|---|---|---|---|
| MongoDB database or cluster | Supabase project and Postgres database | manual | Record owner, region, and source ID. |
| Collection | Staging JSONB table, then destination table | transform | Approve relational and naming semantics first. |
| Document _id | Primary key plus source ID | transform | Preserve stable identity for references. |
| Nested object or array | Relation, array, or JSONB | transform | Choose query and integrity behavior explicitly. |
| User document and password hash | auth.users.encrypted_password | transform | Match Auth column types and test login. |
| Custom user fields | profiles or equivalent table | manual | Do not add arbitrary columns to auth.users. |
| Google or Apple identifier | Auth provider metadata | transform | Test each social path after import. |
| Index or unique constraint | Postgres index or unique constraint | manual | Design from query evidence. |
| Mongo query, Data API call, or change stream | PostgREST, RPC, or Edge Function | manual | Port idempotently and test failure behavior. |
Make the move recoverable.
Create the source-of-truth backup
Preserve MongoDB data, configuration, and operating evidence before any destination write.
- Create a native, restorable MongoDB backup plus logical schema and data exports.
- Inventory collections, types, relationships, indexes, users, files, queries, jobs, and integrations.
- Record counts, checksums, aggregates, sizes, lag, performance, and recovery baselines.
- Hash all immutable backup and migration artifacts.
Proof to capture: A signed manifest reconciles every scoped record class, runtime dependency, export file, count, and hash.
Target schema and Auth map
Define tables, JSONB staging, user import, and RLS before loading production data.
- Inventory source collections and user fields.
- Define explicit destination tables and Auth columns.
- Reject unmapped critical records.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
Repeatable copy and normalize pipeline
Load JSON, normalize with SQL, catch up writes, and cut over deterministically.
- Stage documents in JSONB, then populate relational tables.
- Run a representative pilot including Auth sign-in.
- Reconcile accepted, rejected, and transformed rows.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
The things most likely to hurt.
These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.
Silent type coercion corrupts data
Precision, timezones, encodings, booleans, nested values, or nulls change without a load error.
- Consequence
- Applications make incorrect decisions.
- Mitigation
- Use type fixtures, checksums, aggregates, and invariant queries.
Stop if: Any critical invariant or precision check fails.
Users cannot sign in after Auth import
Empty strings, duplicate emails, or provider metadata fail Auth.users rules.
- Consequence
- Customers are locked out or duplicate accounts appear.
- Mitigation
- Batch-load users, test password and social login, and keep MongoDB available.
Stop if: A representative user class cannot authenticate.
Final delta misses writes
Change capture lags, drops unsupported operations, or stops before writers freeze.
- Consequence
- Source and destination diverge permanently.
- Mitigation
- Monitor lag and reconcile a final consistency point.
Stop if: Lag is nonzero or an unexplained delta exists.
Do the work in this order.
- Days 1–4 · inventory
Inventory and decisions
8–16 hours active3–4 days elapsedOwner review waiting- Inventory MongoDB collections, users, files, queries, and integrations.
- Approve the target schema, Auth strategy, and exclusions.
Depends on: MongoDB and Supabase administrator access
Stop / go checkpointExport?
Go when: Every critical item has an owner and disposition.
Stop when: Consent, billing, access, or system ownership is unclear.
- Days 4–7 · backup
Backup and reconcile
6–12 hours active2–3 days elapsedExport processing waiting- Create a native MongoDB backup and logical exports.
- Reconcile counts, totals, and hashes.
Depends on: Approved inventory
Stop / go checkpointTransform?
Go when: Source totals and export manifests agree.
Stop when: Any critical dataset or configuration is absent.
- Days 7–20 · pilot
Map and pilot
25–70 hours active6–12 days elapsedDestination processing and review waiting- Load a representative subset into staging and normalize it.
- Import Auth users and test password, social, RLS, and query paths.
Depends on: Verified backup
Stop / go checkpointScale?
Go when: Pilot mappings, behavior, access, and evidence pass.
Stop when: Any critical check fails or produces unexplained variance.
- Days 18–35 · cutover
Final delta and switch
8–30 hours active2–6 days elapsedImport or sync propagation waiting- Freeze production writes in MongoDB.
- Apply the final delta, switch clients, and run blocking checks.
Depends on: Passed pilot and approved rollback
Stop / go checkpointOpen production?
Go when: Counts reconcile and one destination system owns production.
Stop when: A source writer remains active or a blocking check fails.
- Days 22–50 · observe
Observe and close
4–20 hours active4–12 days elapsedOperating-cycle evidence waiting- Monitor one complete operating cycle.
- Sign the verification report and close rollback only after stability.
Depends on: Verified cutover
Stop / go checkpointClose rollback?
Go when: No trigger occurs during the agreed observation period.
Stop when: Data, access, delivery, routing, or business results regress.
Cut over with a way back.
Cutover
Make Supabase the only production system without losing the final MongoDB delta.
- Freeze production writes and scheduled actions in MongoDB.
- Export, transform, and reconcile the final delta.
- Apply the approved delta to Supabase tables, Auth, and storage.
- Switch application clients, APIs, and jobs to Supabase.
- Run every blocking verification check and keep MongoDB intact.
Proof to capture: Supabase owns production, totals reconcile, and every blocking check has durable evidence.
Rollback
Return production ownership to MongoDB without losing destination-era changes.
- Stop new writes and scheduled actions in Supabase.
- Restore the prior MongoDB routing, APIs, jobs, and client configuration.
- Export the Supabase post-cutover delta.
- Review and apply safe destination-era changes to MongoDB.
- Run the same blocking checks against the restored source.
Proof to capture: MongoDB again owns production with current data and no duplicate destination action.
- Unexplained critical count or value variance
- Missing or exposed critical data
- Users cannot authenticate
- Failed access, routing, delivery, or integration check
- A critical feature has no safe destination replacement
Prove the migration worked.
Every blocking check must pass. Capture the evidence before cleanup begins.
| Pass | ID | Check | Method | Expected result | Evidence |
|---|---|---|---|---|---|
V-01Blocking | Record reconciliation | Compare counts, checksums, aggregates, and stratified records. | Every scoped record is accounted for. | Data ledger. | |
V-02Blocking | Value fidelity | Run type fixtures covering bounds, nulls, precision, Unicode, and timezones. | No silent coercion or truncation. | Type report. | |
V-03Blocking | Auth sign-in | Test password, email, Google, Apple, and denied accounts. | Approved users authenticate and unknowns are rejected. | Auth log. | |
V-04Blocking | Reference and constraint integrity | Query parents, children, orphans, duplicates, and cascades. | Every critical invariant holds. | Integrity report. | |
V-05Blocking | RLS and roles | Run allowed and denied operations for every role. | Least privilege matches policy. | Access evidence. | |
V-06Blocking | Functional and performance parity | Run production-shaped reads and writes under concurrency. | Results and service objectives pass. | Benchmark report. | |
V-07Blocking | Backup, restore, and rollback | Restore a destination backup and execute the rollback rehearsal. | Recovery objectives and integrity pass. | Recovery report. | |
V-08Blocking | Write authority | Inspect writers, jobs, APIs, and application connections. | Supabase alone accepts approved writes with zero unexplained delta. | Cutover checklist. |
Remove the scaffolding safely.
Safe after: One complete operating cycle, at least seven stable days, and owner sign-off on every blocking check.
- Create final MongoDB exports and archive verification evidence.
- Revoke temporary credentials, API keys, webhooks, and elevated roles.
- Remove obsolete embeds, forms, jobs, integrations, and DNS records.
- Keep the source intact through the approved retention window.
- Cancel paid plans only after billing, legal, and recovery review.
- Schedule the next Supabase backup, access, and migration-playbook review.
When the plan met reality.
First-hand accounts are preferred. Vendor case studies are labeled, and every note below is an editorial paraphrase—follow the link for the full context.
Tarik moved OSM Tactics, a mobile game backend on NestJS and MongoDB, to Supabase while keeping 182,000 users able to sign in. He exported collections to JSON, mapped users into auth.users, and loaded them in batches of 1,000. bcrypt hashes transferred, but empty strings, duplicate emails, and missing Auth columns broke imports. Custom fields went to a profiles table, and Google and Apple IDs became provider metadata. He also warned that Supabase CSV export looked unreliable on 29 March 2025.
- Design the Auth row shape and a separate profiles table before you load users, and treat empty strings as a failure case.
- Test password and social sign-in on a batch, then load the rest in bounded inserts with a duplicate-email report.
- The hard part was Auth.users, not dumping Mongo collections to JSON.
- Keeping the existing bcrypt hashes avoided a forced password reset for the imported cohort.
Ali Khallad describes moving metadata from MongoDB into Supabase Postgres after the project already used Supabase Auth and had grown onto AWS. He published Python scripts for a full-database copy and for table-by-table loads with field maps and defaults. He used the table path because the documents needed reshaping. The write-up stresses backups of both sides, a small test subset, and leaving MongoDB running until the new tables are checked.
- Backup MongoDB and Supabase before any load, then migrate one table with an explicit field map before you attempt a full copy.
- Keep MongoDB online until counts and application reads against the new tables match the signed subset.
- Auth was already on Supabase, so the move was a data-model consolidation rather than a greenfield backend.
- Reshaping documents during the table load mattered more than a one-shot collection dump.
Verify against the primary material.
Platform behavior changes. Check these sources and the review dates above before executing a production migration.
- Supabase: migrating from the MongoDB Data APIAccessed 2026-10-23
- MongoDB: mongoexportAccessed 2026-10-23
- MongoDB: export behavior and BSON fidelityAccessed 2026-10-23