Moving a hosted Postgres backend to Open Source Cloud
Hosted backends bundle a Postgres database with sign-in, file storage and a generated API, which makes the first version of an app quick to build. Leaving is harder, because the database is the easy part. This page is for teams who want plain open source PostgreSQL and services they can run anywhere. If your backend is on Supabase, this is the path we would take.
What maps where
For an app whose backend is a hosted Postgres bundle. Every service on the right is open source and runs in your own workspace.
In a hosted backend: Postgres database
On Open Source Cloud: PostgreSQL
Upstream PostgreSQL. The tables your app created move with pg_dump and pg_restore.
In a hosted backend: Built-in sign-in
On Open Source Cloud: Keycloak
Users keep their passwords, because bcrypt hashes can be imported as they are. Our guide below has the export query and the import script.
In a hosted backend: File storage buckets
On Open Source Cloud: MinIO
S3-compatible. Copy the files with any S3 client, for example aws s3 sync with a custom endpoint.
In a hosted backend: Generated REST API
On Open Source Cloud: PostgREST
Serves a REST API straight from your PostgreSQL schema. Point it at the new database.
In a hosted backend: Generated GraphQL API
On Open Source Cloud: Hasura GraphQL Engine
Only if your app uses GraphQL.
In a hosted backend: Realtime subscriptions
On Open Source Cloud: Centrifugo
A realtime messaging server over WebSocket. It is not a drop-in swap: your app publishes the events itself.
In a hosted backend: Database backups
On Open Source Cloud: Database Backuper
Backs up PostgreSQL to S3-compatible storage, with optional AES-256 encryption.
| In a hosted backend | On Open Source Cloud | Notes |
|---|---|---|
| Postgres database | PostgreSQL | Upstream PostgreSQL. The tables your app created move with pg_dump and pg_restore. |
| Built-in sign-in | Keycloak | Users keep their passwords, because bcrypt hashes can be imported as they are. Our guide below has the export query and the import script. |
| File storage buckets | MinIO | S3-compatible. Copy the files with any S3 client, for example aws s3 sync with a custom endpoint. |
| Generated REST API | PostgREST | Serves a REST API straight from your PostgreSQL schema. Point it at the new database. |
| Generated GraphQL API | Hasura GraphQL Engine | Only if your app uses GraphQL. |
| Realtime subscriptions | Centrifugo | A realtime messaging server over WebSocket. It is not a drop-in swap: your app publishes the events itself. |
| Database backups | Database Backuper | Backs up PostgreSQL to S3-compatible storage, with optional AES-256 encryption. |
What does not move over as it is
Better to know this before you start than halfway through.
- Row-level security tied to the platform. Policies granted to roles such as anon and authenticated, or that call auth.uid(), point at roles and functions that only exist on the hosted platform. Rewrite them for your new sign-in before you restore them.
- The platform's own schemas. The auth and storage schemas belong to the platform, not to your app. Users go to Keycloak and files go to MinIO instead, so dump only the schemas your app owns.
- User ids. Keycloak gives every imported user a new id. The import keeps the old one as a supabase_id attribute, so rows and policies keyed on the old id need updating to the new one. Foreign keys to auth.users also need dropping or repointing, because auth.users does not exist on the new database.
- Edge functions. There is no like-for-like runtime here. The code can run as a Node.js app in My Apps, which may mean changes.
- Client library calls. Code that calls the vendor's client library for sign-in or files needs standard clients instead: an OpenID Connect library and an S3 client.
If your app is mostly tables and queries, the move is mostly configuration plus one step that maps old user ids to new ones. If it leans on realtime and edge functions, plan time to rewrite those parts.
What we have checked
We have not yet timed a full move of a real app from start to finish. This is what we have checked.
- Users moved from Supabase into Keycloak on Open Source Cloud with their bcrypt password hashes. The right password signed in and a wrong one was refused.
- PostgreSQL, Keycloak, MinIO, PostgREST, Centrifugo and Database Backuper are all in the catalog, checked on 20 October 2026.
Not checked yet: a timed move from start to finish, realtime, edge functions and moving a large file store. Try the move on a copy of your project before you switch your users.
The user migration guide: export query, import script and password checkThe steps as a machine-readable recipe for your AI agentThe move, step by step
Create the services
Start PostgreSQL, Keycloak and MinIO from the catalog, or ask your AI agent to do it over MCP. Keycloak keeps its own data in PostgreSQL.
Dump your own schemas
Run pg_dump against the old database with --schema=public (plus any other schema your app created), --no-owner and --no-privileges. Leave the platform's auth and storage schemas out.
Restore and fix the policies
Drop or repoint foreign keys that point at auth.users, then restore into the new PostgreSQL with pg_restore or psql. Rewrite any policy that refers to the platform's roles or auth functions.
Move users and files
Import users into Keycloak with their existing password hashes, as in our guide. Then update the user id columns in your tables to the new Keycloak ids, using the supabase_id attribute the import keeps. Copy files into MinIO with aws s3 sync or any S3 client.
Repoint the app
Put the new connection string, the Keycloak address and the MinIO endpoint in a parameter store, and swap the vendor client calls for standard ones.
Switch over
Freeze writes or run a final sync, then send your users to the new backend. Keep the old project until you are sure, then remove it.
Questions
Can I move a Supabase project to Open Source Cloud?
Yes. The database is PostgreSQL on both sides, so your tables move with pg_dump. Sign-in moves to Keycloak, files to MinIO and the generated API to PostgREST. The parts that take real work are mapping user ids to their new Keycloak ids, row-level security tied to the platform's roles, realtime and edge functions.
Will my users have to reset their passwords?
No, as long as their passwords are stored as bcrypt hashes, which is how Supabase stores them. Keycloak on Open Source Cloud accepted the imported hashes in our test: the right password signed in and a wrong one was refused. Other hash types need a different approach.
Why Keycloak and not another sign-in service?
It is the one we have tested with an import that keeps passwords, and it keeps its data in PostgreSQL. Other sign-in services in the catalog can suit a new app, but we have not tested a password-keeping import into them.
Will I be locked in again?
The services are unmodified open source projects, so the same database, sign-in server and storage can run anywhere else, including on your own servers. A pg_dump moves the data out the same way it came in.
Try it on a copy first
Copy your smallest project, move that one, and check that sign-in, files and queries work before you touch the real one.