Migration Guide6 min read

Cloud to Self-Hosted: Complete Migration Guide

Stack2X Team
Cloud to Self-Hosted: Complete Migration Guide

Moving from Supabase Cloud to a self-hosted instance is one of the most impactful infrastructure decisions a growing startup can make. Done well, it gives you full control over your data, predictable costs, and the flexibility to customize your stack. Done poorly, it means downtime, data loss, and angry customers.

This guide walks you through the entire process from start to finish. No deep DevOps experience required.

Before You Begin: Pre-Migration Checklist

Do not start migrating until these items are in place:

Self-hosted instance is running. Your target Supabase instance should be deployed, accessible, and stable. Whether you are using Docker Compose on a VPS, Kubernetes, or a managed hosting provider, confirm that the Supabase dashboard loads and the API responds.

DNS is configured. Your self-hosted instance needs a domain or subdomain pointed at it. This is how your application will connect after the migration.

SSL certificates are active. Every connection to your Supabase instance should be encrypted. Set up SSL through Let's Encrypt, your hosting provider, or a reverse proxy like Nginx or Caddy before you migrate any data.

You have admin access to both environments. You need database connection strings, API keys, and service role keys for both your Cloud project and your self-hosted instance.

A recent backup exists. Before touching anything, create a full backup of your Cloud project. This is your insurance policy if anything goes wrong during migration.

Skipping any of these steps is the most common reason migrations fail. Fifteen minutes of preparation saves hours of troubleshooting.

The 5-Phase Migration Plan

Phase 1: Audit Your Cloud Project

Before you move anything, you need to know exactly what you are moving. Log into your Supabase Cloud dashboard and inventory everything:

  • Database schemas, tables, views, and functions
  • Row-level security policies
  • Auth providers and user accounts
  • Storage buckets and their access policies
  • Edge functions and webhooks
  • Database extensions that are enabled
  • Environment variables and secrets

This audit serves two purposes. It tells you what needs to migrate, and it gives you a checklist for verification after the migration is complete. Write it down or export it. Do not rely on memory.

Phase 2: Prepare Your Target Instance

With your audit in hand, make sure your self-hosted instance is ready to receive everything:

  • Enable the same PostgreSQL extensions that your Cloud project uses
  • Configure the same auth providers (Google, GitHub, email, etc.)
  • Set up equivalent environment variables
  • Ensure your server has enough storage capacity for your database and file storage
  • Verify that your PostgreSQL version matches or is compatible

The goal is to make the target environment as close to your source environment as possible before any data moves.

Phase 3: Connect Both Instances in Stack2X

This is where the migration tool does the heavy lifting. In Stack2X, connect your Supabase Cloud project as the source and your self-hosted instance as the target. The migration wizard walks you through entering connection details for both environments.

Stack2X will analyze your source project and show you exactly what will be migrated: tables, schemas, auth data, storage buckets, RLS policies, and configuration. You can select which components to include or exclude.

Review this summary carefully. If something looks wrong or missing, address it before starting the migration.

Phase 4: Execute the Migration

With both instances connected and your migration plan reviewed, it is time to run the migration. A few important considerations:

Schedule a maintenance window. Tell your users that the service will be briefly unavailable. Even if the actual migration takes only minutes, give yourself a buffer for unexpected issues.

Freeze writes to Cloud. During migration, you want to prevent new data from being written to your Cloud instance. Either put your app in maintenance mode or temporarily disable write access. This prevents data from landing in the source after the migration has already moved that table.

Run the migration through Stack2X. The tool handles the correct order of operations: schema first, then data, then auth, then storage, then policies. This sequencing matters because dependencies between these components can cause failures if migrated in the wrong order.

Monitor progress. Watch for errors or warnings during the migration. Stack2X surfaces issues in real time so you can address them before moving to verification.

Phase 5: Verify Everything

This is the phase that separates a smooth migration from a disaster discovered two weeks later. Go through your audit checklist from Phase 1 and confirm every item:

  • Row counts match between source and target tables
  • Auth users can log in on the new instance
  • Storage files are accessible and intact
  • RLS policies are enforced correctly
  • Application features work end-to-end against the new instance
  • Edge functions and webhooks respond as expected

Do not skip application-level testing. Database-level verification tells you the data is there, but only testing your actual product confirms that everything works together.

Post-Migration Steps

Update your application configuration. Point your app's Supabase client to the new self-hosted URL and keys. Deploy this change.

DNS cutover. If you are routing through a custom domain, update your DNS records to point at the self-hosted instance. Allow time for DNS propagation.

Monitor closely for 48 hours. Watch error logs, database performance, and user reports. Most migration issues surface within the first two days.

Keep your Cloud project active temporarily. Do not delete your Cloud project immediately. Keep it running in read-only mode for at least two weeks as a fallback. Once you are confident the self-hosted instance is stable, you can decommission it.

Common Pitfalls to Avoid

Migrating without freezing writes. If users are still writing data to Cloud while you migrate, you will end up with inconsistencies. Always freeze writes first.

Forgetting storage files. A database migration without storage leaves your app with broken file links. Make sure storage buckets and objects are included.

Ignoring RLS policies. Your data might arrive on the self-hosted instance, but without the correct security policies, it could be exposed publicly or inaccessible to users.

Skipping the verification phase. "It looks like it worked" is not verification. Go through your checklist methodically.

Not having a rollback plan. If something goes wrong mid-migration, you need to be able to point your app back at the Cloud instance quickly. Keep that option available until you are fully cut over.

Moving Forward

A well-executed migration from Cloud to self-hosted should feel anticlimactic. No drama, no surprises. Just your same product running on infrastructure you fully control. Follow the phases in order, verify thoroughly, and give yourself permission to take it slow. Speed is less important than getting it right.

Ready to migrate?

Start your free migration today. No credit card required.