Open-source alternative to Cloud Firestore

Self-hosted Supabase, Appwrite and PocketBase can replace Firestore's document database, but each changes the data model, security rules and realtime behavior. This page maps the options and the work involved.

On this page

Which open-source database replaces Cloud Firestore for your app

If your Firestore bill keeps growing, or your residency or lock-in concerns have put the document database under review, the first decision is which self-hosted engine will hold your data. The main options are Supabase, which gives each project a Postgres database exposed through PostgREST, Appwrite, which provisions PostgreSQL by default and also supports MariaDB and MongoDB, and PocketBase, which embeds SQLite in a single executable. Each fits a different app: Supabase suits teams that want relational modeling and SQL, Appwrite suits teams that want a broader backend bundle with a choice of engines, and PocketBase suits small apps with a single server and modest scale.

Cloud Firestore is a NoSQL document database, so moving off it is a data model change, not a configuration change. Collections and subcollections of JSON-like documents have to be reshaped into tables, join tables or documents, depending on the target. Nested data, denormalized copies and the way queries were indexed around document paths all need a decision before any data moves. Plan the new schema first, then decide how each Firestore query becomes a SQL query, a Postgres view or an Appwrite database query.

Security rules also change shape. Firestore rules are written against document paths and request data, while Supabase relies on Postgres row level security policies and Appwrite uses permissions attached to documents and collections. Treat rule translation as a rewrite with its own test cases, and confirm each engine's listener and realtime behavior against your app's access patterns before you commit to one.

How Firestore capabilities map to open-source options

This table maps Firestore's collections, subcollections, security rules, listeners, indexes, transactions and batched writes to Supabase, Appwrite and PocketBase. Read each coverage note as a prompt to test the feature against the product's current documentation before committing to a data model.

Firestore capabilitySupabase (Postgres, PostgREST, RLS)Appwrite databasesPocketBase collections
Collections and documentsTables and rows. Documents with stable fields map to columns, while variable fields usually need a jsonb column. Coverage: good for structured data, requires schema design.Collections and documents with typed attributes, backed by PostgreSQL by default. Coverage: good, but confirm attribute limits and document size in current docs.Collections with typed fields and JSON fields. Coverage: good for smaller data sets, with schema changes made through the collection editor or migrations.
Subcollections and nested documentsFlatten into child tables with foreign keys. Queries across levels become joins or views. Coverage: needs flattening and join planning for every nested path.Usually modeled as separate collections linked by relationship attributes. Coverage: needs flattening, and confirm how relationship attributes behave in your version.Usually modeled as separate collections with relation fields. Coverage: needs flattening, and relation depth should be tested against your query patterns.
Security rulesPostgres row level security policies on tables, enforced by PostgREST with the user's JWT. Coverage: rules must be rewritten as SQL policies, and every table needs explicit policies.Permissions set per document, collection or bucket, with role-based and user-based access. Coverage: confirm which permission scopes apply to your access pattern.API rules per collection that filter list, view, create, update and delete access, written as expressions. Coverage: rules need a full rewrite and review, not a port.
Realtime listenersPostgres changes streamed through Supabase Realtime, subject to RLS. Coverage: confirm how filters and payload size behave in the self-hosted release you deploy.Realtime subscriptions to channels for documents and collections. Coverage: confirm subscription scope and reconnect behavior in current docs.Realtime subscriptions to collection and record changes through the SDK. Coverage: test connection counts and reconnect handling on your planned server size.
Indexes and query shapeStandard Postgres indexes, including composite and partial indexes. Coverage: Firestore's composite index rules do not carry over, so queries should be reviewed against Postgres plans.Indexes defined on attributes, with query limits enforced by the API. Coverage: confirm supported index types and query operators in current docs.Indexes defined per collection, with SQLite query behavior. Coverage: confirm index options in the release you use, since SQLite differs from Firestore's query model.
Transactions and batched writesMulti-statement transactions in Postgres, usually through a server function or RPC call. Coverage: client-side batches must move to server code or stored procedures.Bulk and related writes are handled through the server API, with transactional behavior to confirm. Coverage: verify atomicity guarantees for your write pattern.Batch requests are available through the API, with SQLite transactions on the server. Coverage: confirm batch endpoint behavior and limits in the current version.
Operations and recoverySelf-hosted with your own Postgres backups. Managed backups and point-in-time recovery are not available when self-hosting. Coverage: plan backups and restores yourself.Built-in datastores run a single replica without failover in the Helm chart. Coverage: production data should use managed databases or operators.Single SQLite file with dashboard backups. PocketBase scales vertically on one server. Coverage: confirm backup and restore procedures match your recovery targets.

Which option fits your Firestore workload

Each option replaces Firestore's document model with a different data layer, so the right choice depends on how your data is shaped, how many users you expect, and how much operational work your team can take on. The cards below set out when each platform fits and what it asks of you in return.

Supabase self-hosted for relational data

Supabase gives each project a Postgres database with PostgREST exposing tables as an API, and it runs in your infrastructure from a Docker Compose configuration published under Apache-2.0. It fits teams whose Firestore collections already behave like related records, since joins, constraints and row level security map onto Postgres. Check the trade-offs before committing: self-hosted Supabase runs as a single project, managed backups and point-in-time recovery are not included, and support comes from the community rather than a vendor contract. Confirm your backup design early.

Appwrite self-hosted for mixed services

Appwrite is BSD-3-Clause licensed and bundles Auth, Databases, Storage, Functions and Realtime in one stack, with PostgreSQL as the default for new installs. Its document model is closer to Firestore's collections, but DocumentsDB for schemaless JSON ships disabled until the PostgreSQL and MongoDB engines it needs are deployed. The official Helm chart runs its built-in datastores as single replicas without failover, so production data should move to managed services or operators. Ask your team which datastores they will run and who owns their availability.

PocketBase for small single-server apps

PocketBase is a single MIT-licensed executable with an embedded SQLite database, built-in auth and realtime subscriptions, and it runs with ./pocketbase serve. It suits small apps with modest concurrency that can live on one server and accept vertical scaling only. The project warns that backward compatibility is not guaranteed before v1.0.0 and is not recommended yet for production-critical applications, and it is maintained on a volunteer basis with no paid support. Plan for manual upgrade steps and a tested restore process before you rely on it.

Document modeling and query fit

Before choosing a platform, map your Firestore collections, subcollections and listener queries to the target model. Deeply nested documents and queries that fan out across subcollections usually need reshaping into tables or indexed JSON fields, while simple collections with per-document access rules translate more directly. Build a short list of your ten most frequent reads and writes and test each one on the candidate platform. This check is the same regardless of which option you pick.

Operations and support ownership

Self-hosting moves patching, backups, secret rotation and capacity planning to your team, and each platform releases often, so upgrades arrive regularly. Supabase and Appwrite both document their Docker or Helm deployments, while PocketBase has no official Docker image and recommends a systemd service. Ask who will watch security advisories, who can restore a backup on a test host, and whether you need a retainer or internal staffing to cover those tasks.

How collections and subcollections translate into tables or documents

Supabase gives each project a Postgres database, so a Firestore collection usually becomes a table and a subcollection usually becomes a child table that holds a foreign key to its parent row. Firestore's document paths, such as a users/{uid}/orders/{orderId} path, become a orders table with a user_id column referencing auth.users. Client apps still reach these tables through the PostgREST API, so reads and writes keep a familiar shape while the schema becomes explicit.

  • Collections to tables: Each top-level collection becomes a table with a primary key, typed columns and, where a document held nested maps, either JSON columns or normalized child tables.
  • Subcollections to foreign keys: A subcollection becomes a child table with a parent_id foreign key and an index on that column, which replaces the implicit path nesting.
  • Document references to joins: Firestore reference fields become foreign keys, and a client that followed several reads now uses one query with an embedded resource or a database view.
  • Denormalized reads to views or joins: Data copied into several documents for fast reads may be unnecessary in Postgres, so reads move to joins, views or materialized views, and triggers keep any remaining copies consistent.
  • Security rules to row level security: Access that Firestore rules expressed per document path is rewritten as Postgres row level security policies on each table.

Illustrative example: a users/{uid}/orders subcollection might become an orders table keyed by id with a user_id foreign key. Confirm with your own data whether nested arrays should be JSON columns or child tables, since that choice changes write patterns and indexes.

Why Firestore security rules and listeners need rewriting

Firestore security rules are evaluated per document path, so each read or write is allowed or denied by a rule attached to a collection or document match, often checking the request's auth token and the stored document fields. The replacements express access in different places. Supabase applies Postgres row level security policies to each table, Appwrite attaches permissions to documents, collections and buckets, and PocketBase uses API rules on each collection. None of these is a line-for-line translation of a Firestore rule, so each rule needs to be re-expressed against the target model and checked for the same outcome. Confirm with each vendor's documentation exactly which expressions, role checks and token claims are available before you design the policies.

Listeners need a different plan. A Firestore onSnapshot listener on a collection or query becomes a Supabase Realtime channel subscribed to Postgres changes, an Appwrite Realtime subscription on a channel such as a database collection, or a PocketBase realtime subscription on a collection. Each target delivers change events differently, and the events may not reflect the same filtering or ordering behavior your queries rely on. Check how each platform applies access rules to realtime events, since a subscriber should receive only the rows they can read. Ask the vendor or test in your own environment whether filtered and composite queries behave as your app expects.

Testing is where most of the effort goes. Build a test suite from real client queries captured from your app, including reads, writes, listeners, unauthenticated calls and cross-tenant attempts, and run it against each rule set. Expect the rewrite, not the data copy, to be the largest effort item, because rules and listeners are spread across client code and the target's permission model. Ask any implementation partner to fix the scope of rule rewriting and realtime testing in writing, and confirm each parity claim with a passing test rather than assuming a feature matches.

How to move Firestore data without losing users or records

This sequence moves Firestore collections into a target schema that you have tested in staging, with record counts and relations checked before any traffic moves. It ends with a cutover you can roll back, after Firebase Auth password hashes are confirmed to work on the new platform.

  1. Inventory collections, subcollections and listeners

    List every top-level collection, every subcollection path, and the document counts and field types in each, using the Firebase console and a sample of documents. Your team owns this step, with the product owner confirming which collections are still active. Record which client listeners and Cloud Functions read or write each path, because those become your change list. The step is done when you have a written inventory that a second engineer has reviewed and that matches what the production apps actually query.

  2. Design the target schema and access model

    Map each collection to a Postgres table (for Supabase) or an Appwrite database collection, and decide how subcollections become foreign keys, join tables or nested JSON fields. Decide which documents need typed columns and which can stay as JSON. Draft row level security policies or Appwrite permissions for each table, based on the rules you exported. Confirm the design with the application team by checking it against the queries recorded in the inventory. The output is a schema document and a permission matrix that the team signs off before any data is exported.

  3. Confirm Firebase Auth hash compatibility first

    Treat user migration as a dependency, not a side task. Export Auth users with the Firebase CLI so the password hashes and the project's scrypt parameters are included, then confirm the target platform accepts that hash type: Supabase imports into auth.users using those parameters, and Appwrite's Users API accepts imported Scrypt modified hashes. Test a sample login on staging. If a user's hash cannot be verified, plan a password reset for that group. The step is done when a test account signs in on the new platform without a reset. For the full user path, see the sibling topics on migrating from Firebase to Supabase and to Appwrite.

  4. Export and load data into staging

    For Supabase, use the supabase-community firebase-to-supabase scripts, which read Firestore data and write it into Postgres tables that follow your target schema. For Appwrite, run the Migrations feature against the Firebase project with a service account that has the roles Appwrite documents for that import. Load into a staging instance of the target platform, never production. Keep the raw Firestore export as an archive. The step is done when every collection has loaded without script errors and the load logs are saved with the export files.

  5. Validate counts, relations and field types

    Compare document counts per collection against the Firestore inventory, and compare child record counts for each subcollection against their parent references. Check that timestamps, numbers, references and arrays kept their types, because Firestore's field types do not always map one to one onto Postgres columns. Sample at least one record per collection and compare it field by field with the source. Write the results into a reconciliation report. The step is done when every mismatch is either fixed or documented with an agreed decision from the data owner.

  6. Rebuild security rules and test access

    Translate each Firestore security rule into row level security policies, Appwrite permissions or, for smaller apps, PocketBase collection rules. Firestore rules and Postgres policies evaluate differently, so test each rule with real user tokens from staging, covering allowed reads, denied reads, writes and cross-tenant access. Include the admin paths that Cloud Functions used to take. Your security engineer owns the test matrix. The step is done when every test case in the matrix passes and the results are attached to the cutover record.

  7. Run parallel reads against the new backend

    Point a small share of read traffic, or a shadow read path in a staging-equivalent environment, at the new backend while Firestore remains the source of truth. Compare the responses for the same queries and log any difference in shape, order or missing fields. Replace listeners with the target's realtime subscriptions in the same window, and measure whether updates arrive as expected. The check is complete when the mismatch log is empty for an agreed period and the product owner accepts the results.

  8. Cut over and keep a rollback path

    Freeze writes to Firestore, run a final delta export of records changed since the first load, apply that delta to the target, and repoint the apps and the write paths at the new backend. Keep Firestore in read-only mode for a defined rollback window that your team sets before the cutover. Confirm backups on the self-hosted side, since self-hosted Supabase and Appwrite do not give you managed point-in-time recovery. The cutover is done when production writes succeed on the new backend, the delta reconciliation matches, and the rollback runbook has been rehearsed.

Questions buyers ask before replacing Firestore

What does moving off Firestore cost, and who gets paid for what?

The cost splits into one-time work and recurring spend. One-time work covers the migration itself: exporting Firestore data, reshaping documents into tables or collections, moving Auth users, moving files, and rewriting client code and security rules. Recurring spend covers the servers or cloud instances that host the platform, the storage and backup capacity, and the people who patch and monitor it. Your own engineers, an implementation partner, or both may be paid for these pieces. For a hosted Supabase or Appwrite plan, the Pro tier is listed at $25 per month on each vendor's pricing page, but self-hosting removes that subscription and replaces it with infrastructure and operations. Ask any partner for a quote that separates the migration fee, the infrastructure you will pay directly, and the ongoing support retainer.

Can our own team migrate from Firestore without outside help?

Often yes, if the team already runs containers and a relational database and has someone comfortable with SQL and authentication. The hard parts are the data model change from documents and subcollections to tables and foreign keys, the rewrite of client SDK calls, and re-expressing security rules as Postgres row level security or the equivalent in Appwrite or PocketBase. Supabase documents a Firestore migration path, and Appwrite's Migrations feature imports Firebase projects, so vendor tooling covers part of the work. Test the password hash import with real accounts before cutover. Teams without these skills usually add a partner for the design and testing phases and keep operations in-house. Decide early which parts you will own after handover.

How long does a Firestore migration take, and what drives the duration?

Duration depends on the shape of your data and app, not on a fixed rule. The main drivers are the number of collections and subcollections that must be flattened into tables, how many client screens and queries depend on Firestore's SDK behavior, how many security rules must be rewritten and tested, the volume of documents and files to copy, and whether your users can tolerate a cutover window. Migrations that move Auth users also need time to confirm that password hashes validate. Ask any provider for a timeline built from a written scope, with milestones for schema design, data migration rehearsals, client changes, and a cutover and rollback plan.

What replaces Firestore's per-operation billing, and what recurring costs appear instead?

Firestore bills for reads, writes and deletes, plus storage and network use, so costs rise with every query your app runs. A self-hosted platform replaces that meter with fixed infrastructure. Supabase's self-hosting guide lists minimum requirements of 4 GB RAM, 2 CPU cores and a 40 GB SSD, and recommends 8 GB RAM, 4 cores and 80 GB. Appwrite's installation guide requires 2 CPU cores, 4 GB of RAM and 2 GB of swap. Recurring costs then include servers or cloud instances, object storage for files, off-site backups, monitoring, and the staff time to apply upgrades. Production setups usually need managed databases or operators for replication, because the Appwrite Helm chart docs note that its built-in datastores run a single replica without failover. Ask for these components priced separately.

Can PocketBase handle production load after leaving Firestore?

PocketBase can suit small apps, but its own documentation says it is not recommended for production critical applications yet. Its FAQ describes embedded SQLite in WAL mode with no plans for other databases, vertical-only scaling on a single server, and a claim of 10,000+ persistent realtime connections on a $4 Hetzner CAX11 VPS. Full backward compatibility is not guaranteed before v1.0.0, so upgrades may need manual steps. The FAQ also says the project is volunteer-maintained with no paid team behind it. If you need multi-node scaling, a managed database or formal support, Supabase or Appwrite fit those needs better. Load-test your own workload before deciding.

Can we choose where the database is located for data residency?

Yes, but only if you choose the location yourself. With a self-hosted platform, the database runs wherever you deploy it, including an EU data center, a government region or an air-gapped network. Firestore's location cannot be changed after provisioning, and Firebase Authentication processes data only in the United States, so Firestore alone cannot keep auth and data together in the EU. Supabase Cloud asks you to pick one of 17 AWS regions for a project. Confirm with your legal or compliance team which systems hold personal data, including logs, backups, file storage and email delivery, because each one must sit in the approved location.

What support is available for self-hosted Supabase or Appwrite releases?

Community support is the default for self-hosted Supabase. Supabase's self-hosting docs say it is community-supported through GitHub Discussions, GitHub Issues, Discord and Reddit, and that enterprises should contact its Growth Team. Appwrite is open source under BSD-3-Clause, and its releases move quickly, with 2.5.0 released on October 13, 2026, so upgrades need a tested process. Self-hosted Supabase releases also bundle specific upstream versions, and some changes, such as Storage database migrations, are one-way and require a backup first. Any independent support you buy comes from a contract with a provider, such as a retainer for upgrades, patching and incident response. Ask for the response expectations in writing.

Which Firestore features do not carry over unchanged to self-hosting?

Several hosted conveniences do not transfer, and you should plan replacements for them. Supabase's self-hosting docs list branching, managed backups, point-in-time recovery, ETL and the Management API as unavailable when self-hosting. Firestore's managed exports to Cloud Storage will be replaced by your own backup tooling. Listener behavior also changes: Firestore's real-time listeners become Postgres-backed Realtime channels in Supabase, subscriptions in Appwrite, or realtime subscriptions in PocketBase, each with different semantics. Client SDK calls and security rules need rewriting. Check each feature your app uses against the target platform's documentation before you commit to a schedule.

Running the new database beside the rest of Firebase during cutover

Firestore rarely moves in isolation. Auth, Storage and Functions usually keep running on Firebase while data is copied and clients are switched, so the team must choose how writes stay consistent and when each service moves. The cards below compare the common patterns and the dates that limit how long a split setup can last.

Dual writes from the client

The app writes to Firestore and the new Postgres or Appwrite database in the same release, so both stores stay current during the transition. This is simple to reason about, but a failed second write leaves the stores different, and every client version in the field must send both writes. Check how the team will detect and repair drift, and whether older app builds can still reach Firestore before you rely on this pattern.

Change capture from Firestore

A single writer stays in Firestore while a change feed or sync job replays each document change into the new database. Clients keep their current behavior, and the sync job can be stopped and restarted. The trade-off is lag between stores and the need to handle deletes, nested data and conflicting edits in the replay logic. Confirm the change capture method and its delivery guarantees in the Firestore and target platform documentation before you choose it.

Read-only freeze window

Writes to Firestore are stopped for a short, announced period, the final export and import run, and the apps switch to the new backend. This gives the cleanest copy with no conflicts, at the cost of user-visible downtime that grows with data volume and retries. Agree the freeze window with product owners, test the import rehearsal end to end, and confirm how offline clients will queue or reject writes during the freeze.

Keeping Auth and Storage on Firebase

Firebase Authentication and Cloud Storage can remain in place while only the document data moves, so the app verifies Firebase ID tokens against the new database. This reduces the scope of the first cutover, but the team must check that row or document access rules still work with tokens issued outside the new platform. Note that Firebase Authentication processes data only in the United States, which matters if the new database must stay in another region.

Functions and triggers during the split

Cloud Functions that react to Firestore writes will stop firing once the source collections stop changing, and any function that writes back to Firestore must be paused or repointed. Map each trigger to its replacement and decide which side is authoritative for every write path. Cloud Functions use the Blaze plan, so review the billing impact of keeping them active during the transition.

Firebase dates as planning limits

Firebase Dynamic Links shut down on August 25, 2025, so any deep links still tied to it must already have moved. Firebase Extensions will shut down on March 31, 2027, after which deployed extensions can no longer be updated, reconfigured or uninstalled. Treat March 31, 2027 as the outer limit for any extension-driven writes to Firestore, and plan the coexistence window to finish well before it.

What your team must operate after self-hosting

Your team inherits every upgrade, and the three candidate platforms make that work differ sharply. Self-hosted Supabase ships as a Docker configuration that bundles specific upstream services, so each release, such as 0.8.3 on October 16, 2026, pulls new Auth, PostgREST and Realtime versions that the operator must pull and recreate. The 0.8.3 changelog flags a one-way Storage database migration that requires a database backup before updating, so the platform owner must take and test that backup first. Appwrite 2.5.0, released October 13, 2026, needs the same discipline with its Compose or Helm files, and PocketBase v0.40.5 (October 8, 2026) is pre-1.0, so its documentation warns that upgrades may need manual migration steps from the changelog. Assign one owner to read each changelog before any upgrade window and to keep a rollback plan.

Backups and point-in-time recovery are the gap most likely to surprise a team coming from Firestore, where managed exports and point-in-time options sit with the provider. The self-hosting docs list managed backups and PITR as unavailable for self-hosted Supabase, so your database administrator must design Postgres backups, retention and restore tests on your own storage, and confirm that Storage objects are backed up alongside the database. Appwrite's Helm chart docs say its built-in PostgreSQL, Redis, ClickHouse and object storage each run a single replica without replication or failover. High availability therefore means provisioning a managed or operator-run Postgres with replication, an external or replicated object store, and a highly available Redis, then configuring Appwrite to use them. Confirm with your platform team who pays for and staffs those services, since they are recurring costs that a stock install does not include.

How DeployOpen scopes and delivers a Firestore replacement

DeployOpen plans, implements, customizes, integrates, hardens, backs up, upgrades, documents and supports self-hosted open-source platforms inside the client's own infrastructure. For a Firestore replacement, that means agreeing in writing which collections move to Postgres tables, Appwrite databases or PocketBase collections, and which data-access rules, listeners and client code change with them.

How we scope

  • Inventory every Firestore collection, subcollection and security rule, and record which ones carry users, files or listeners.
  • Choose the target platform (Supabase, Appwrite or PocketBase) against your scale, region, team skills and data residency needs.
  • Agree the written scope, deliverables and timeline before work starts, since most engagements are fixed-scope.

How we build

  • Design the relational or document schema, then map each security rule to row level security, Appwrite permissions or PocketBase API rules.
  • Build and test the migration scripts for Firestore data, Auth users with their password hashes, and Storage files in a staging copy.
  • Rebuild client listeners and queries against the new SDK, and run security testing on the access rules before cutover.

How we hand over

  • Document the schema, access rules, backup routine, upgrade steps and the known gaps between Firestore and the target platform.
  • Deliver a rollback plan and a tested backup and restore procedure, with the data location and hosting decisions recorded.
  • Walk your engineers through the runbook so the team can operate, patch and upgrade the stack after handover.

How we support

  • Ongoing support, upgrades and continuous security testing are available as retainers after the initial handover.
  • Upgrade planning covers breaking changes in each release, including migrations that require a database backup first.
  • Ask for the support boundaries in your quote, because self-hosted Supabase and Appwrite are community-supported by default.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.