Migrate from AWS Amplify to Supabase

Moving an Amplify Gen 2 backend to self-hosted Supabase means reshaping DynamoDB into Postgres, moving Cognito users without their passwords, rewriting AppSync and Lambda logic and copying S3 files. This page lays out what moves cleanly, the sequence and what drives effort.

On this page

How do you migrate from AWS Amplify to Supabase without a big-bang cutover?

Yes, moving an Amplify backend to self-hosted Supabase is practical, but it is a re-platforming project, not a lift and shift. It touches data, identity, API logic and files at the same time, and it is usually run by the platform or backend team with outside help. Teams that weigh a renewal, a data residency requirement or lock-in concerns tend to ask this question because the Amplify backend is spread across Cognito, AppSync, DynamoDB, Lambda and S3, and each piece has its own export path and its own rewrite.

Supabase is an Apache-2.0 stack built on PostgreSQL, so the data model changes from DynamoDB key-value tables to relational tables with schemas, keys and row-level access rules. That makes the work reshaping and rewriting rather than a file copy. DynamoDB exports land in S3 as JSON, and someone must map items to tables, decide how nested or access-pattern-driven data is normalized, and rebuild the authorization logic that AppSync resolvers and Lambda functions enforced. Ask your team to inventory every resolver and function before choosing a sequence, because each one becomes either a SQL policy, a PostgREST call, an Edge Function or a service you keep running.

A staged cutover keeps the Amplify app live while data and users move in phases: first a read-only copy of the data in Postgres, then identity, then writes, with each step checked against the running app. Confirm the exact export and hash-handling options for your Cognito pool and your Amplify version before you commit to a plan, and check the self-hosting docs for the features you depend on, since some hosted capabilities are not available when you self-host. Plan the cutover window and rollback path in writing before work starts, and treat the Supabase self-hosting guide as the reference for what the self-hosted stack includes.

Which Amplify capabilities map cleanly to Supabase and which need rework

This table pairs each Amplify Gen 2 capability with its closest self-hosted Supabase equivalent and a migration note of clean, needs rework or gap. Read the notes as effort signals: clean items move with data and configuration, rework items need code or schema changes, and the gap item needs a plan before cutover.

Amplify capabilitySupabase equivalentMigration note
Cognito user poolsSupabase Auth (GoTrue) with self-hosted user tables in PostgresGap for password transfer. Confirm with Supabase how your Cognito hashes can be imported before promising users no reset.
DynamoDB tablesPostgres tables exposed through PostgRESTNeeds rework. Single-table key designs must be reshaped into relational tables with foreign keys and indexes.
AppSync GraphQL APIPostgREST REST endpoints, Postgres views and functionsNeeds rework. Each resolver must be rewritten as a view, RPC function or client query, with authorization moved to policies.
Lambda functionsEdge Runtime on Deno, or an external serviceNeeds rework. Node.js Lambda code must be ported to Deno, so libraries and runtime APIs need review.
S3 storageSupabase Storage with buckets and policiesClean for object copying. Access rules must be rewritten as Storage policies on the storage schema.
Realtime subscriptionsRealtime service on Postgres changesClean for simple table events. Confirm channel and filter behavior against your current AppSync subscriptions.
Row-level access in authorization rulesPostgres row-level security policiesNeeds rework. Amplify owner and group rules must be expressed as policies and tested per role.

What data, users and files move, and what has to be rebuilt by hand

An Amplify Gen 2 backend does not export as one package. DynamoDB tables, Cognito users, S3 objects and the AppSync and Lambda logic each move by a different path, and each path ends in a different Supabase component. The cards below set out what moves as data, what has to be designed or rewritten, and what the Supabase copy guides do not cover for an Amplify source.

DynamoDB tables become Postgres

Export each table to S3 from DynamoDB, which requires point-in-time recovery on the table, then read the export in DynamoDB JSON or Ion. The export holds items, not a schema, so you design the relational tables, primary keys and foreign keys by hand and map each attribute to a column type. Nested maps and lists need a decision: normalize them into child tables or keep them as jsonb. Confirm the export format options and table size limits against the AWS documentation for your account and Region before you plan the transform.

Cognito users without passwords

The Cognito ListUsers API returns identifiers, attributes and group membership, but not password hashes, so users cannot be moved with their passwords intact. Map the sub value and email to Supabase Auth users, carry group membership into app roles or claims, and decide between a forced password reset, a magic link or an invitation flow. Check the Cognito list limits and pagination behavior for your user pool in the AWS documentation before scripting the export.

S3 objects mapped to Storage buckets

Copy S3 objects to Supabase Storage with a script that walks the source bucket and writes each object to a bucket you create. Amplify stores files under paths set by the storage access rules, so decide how each prefix becomes a bucket or a folder, and carry content type and custom metadata across. Paths that users or the app reference in the database need rewriting in the same run. The Supabase copy guide for Storage targets Supabase Cloud projects, so the Amplify-side script is custom work.

AppSync rules rewritten as SQL policies

AppSync resolvers and allow rules in the Amplify data definition do not translate line by line. Each query becomes a Postgres query or view, and each owner or group rule becomes a row-level security policy that PostgREST enforces for every client request. Test the policies with users from each group, because a missing policy denies access silently. Plan this rewrite with the front end, since client calls change from GraphQL to the Supabase client libraries.

Lambda functions ported to Edge Functions

Each Lambda function and DynamoDB stream trigger needs a new home. Request handlers that run on user calls can move to Supabase Edge Functions, which run on Deno, while long-running jobs or functions that need a different runtime usually belong in a separate service on your own servers. Database triggers replace stream-driven logic where the work stays in Postgres. Review each function's IAM permissions, because those grants do not carry over, and confirm the self-hosted Edge Runtime version you deploy.

What the migration sequence looks like from inventory to decommission

The sequence moves an Amplify backend to self-hosted Supabase in controlled stages, so each stage produces evidence that the next one depends on and the old stack stays available until rollback is no longer needed.

  1. Inventory every Amplify resource and owner

    List every DynamoDB table, Cognito user pool, S3 bucket, AppSync resolver, authorization rule, Lambda function and client SDK call in the Amplify backend, and name an owner for each item. Record which client screens and background jobs call each one, since those call sites decide what must be replaced before cutover. The output is an inventory sheet that the team signs off, with a field mapping document started for each DynamoDB table and each Cognito attribute. Confirm the inventory against the deployed CDK code, not only the console, so resources created outside the backend definition are not missed.

  2. Pilot one bounded feature on self-hosted Supabase

    Choose one feature with a small, well-understood data set, such as a read-mostly table and the users who access it, and rebuild it on a self-hosted Supabase instance. Stand up the Docker Compose deployment from the supabase/supabase docker directory, replace the placeholder secrets before first start, and test sign-in, row-level access rules, queries and file reads against it. Write the Postgres schema and the access policies from the authorization rules captured in the inventory. The output is a tested auth path and a short report listing which Amplify behaviors matched and which required changes in client code.

  3. Run Amplify and Supabase in parallel

    Keep the Amplify backend live and move the rest of the data on a schedule, either by replaying writes into Postgres or by repeating exports from DynamoDB to S3 and importing them. Migrate password hashes only where the source hash format is supported, and otherwise plan password resets for affected users. Run the same reads against both systems and compare the results for each table, user and file. The output is a reconciliation report that lists every mismatch, its cause and its fix, and a list of client features still reading from Amplify.

  4. Cut over with a frozen write window

    Announce the window, freeze writes to Amplify, run the final DynamoDB export and Cognito and S3 copies, and import them into Supabase. Switch the client configuration to the Supabase URL and keys, then verify sign-in, a sample of reads and writes, and file access from the production app before reopening writes. Keep the Amplify stack and its data intact so the team can switch the client back. The output is a signed-off cutover checklist and a rollback plan that names the trigger for rollback and the person who can execute it.

  5. Decommission Amplify after rollback expires

    Once the agreed rollback period has passed without a need to return, archive the final Amplify exports, the reconciliation reports and the CDK code in access-controlled storage. Remove Amplify resources in an order that starts with client-facing paths and ends with data stores, and confirm each deletion against the inventory. Keep copies of audit and access logs required by your own retention policy. The output is a decommission record that maps each removed resource to its archive location and the sign-off that approved its removal.

What drives the effort and duration of an Amplify to Supabase move

This table lists the inputs that change how much work an Amplify to self-hosted Supabase move involves, why each one matters and how to keep it under control. Read it as a checklist for scoping, since most of these drivers are fixed by the current Amplify backend before any work begins.

DriverWhy it mattersHow to keep it down
DynamoDB tables and access patternsEach table must be reshaped into Postgres tables, and access patterns built around partition keys often need new indexes and query logic.Inventory tables and key designs early, and map each access pattern to a SQL query before exporting data.
Number of users and password migrationCognito does not list passwords, so moving users without a reset depends on whether hashes can be obtained and mapped to the target Auth service.Confirm with the team whether a reset flow is acceptable, and plan a staged migration for users who must sign in again.
AppSync resolvers and authorization rulesEach GraphQL resolver and owner or group rule must be rewritten as an API route, a Postgres function or Row Level Security policy.Count resolvers and rules, group them by pattern, and reuse one policy template for similar access checks.
Lambda functions and triggersEvery function, including Cognito triggers and DynamoDB stream handlers, needs a replacement in Edge Functions, database triggers or an external service.List each trigger and its inputs, and remove functions that only mirror behavior Postgres already provides.
S3 objects and folder structureObject count, total size and access rules determine copy time and how storage paths and signed URL logic change.Export an object inventory, decide which prefixes to keep, and copy only live objects.
Client apps and SDK callsWeb and mobile apps built on the Amplify libraries need new client code, auth flows and data calls, and each platform is tested separately.Group client calls by feature, and ask for a count of web and mobile releases that must ship together.
Parallel environmentsKeeping development, staging and production running on both stacks during cutover multiplies configuration, secrets and data sync work.Decide the cutover window and limit parallel running to the environments that need it.
Server size and high availabilitySelf-hosted Supabase sizing depends on load and data volume. PostgreSQL does not provide automatic failover on its own, so failover tooling and standby servers are added work, and PgBouncer is a separate connection pooler to plan for.Size from observed Amplify traffic, decide whether automatic failover is required, and ask the scope to list each external failover and pooling tool.

What usually goes wrong in this migration and how to prevent it

Most failed Amplify-to-Supabase moves break at the seams between services: users, data shape, access rules, operations and upgrades. Each card below names one of these seams, what goes wrong there, and the check that prevents it. Run the password, authorization and restore checks before the cutover date is fixed, not after.

Password path blocks users at cutover

Cognito does not export password hashes through ListUsers, so the password path must be settled before any user is moved. If the import cannot carry hashes across, every user faces a forced reset on the day of cutover, and support volume follows. Test the chosen path early with a copy of real user records: confirm that a sample of imported accounts can sign in, that the hash type is supported by the target auth service, and that the reset flow works end to end. Settle this before anything else is scheduled.

DynamoDB access patterns fail as joins

DynamoDB tables are often designed around known key lookups, with related data duplicated into one item. Moved into Postgres tables, those same reads become joins across normalized tables, and queries that were fast by key can scan large tables. Before cutover, list every query the app runs, rewrite the schema for relational access, add indexes for the filters the app actually uses, and run those queries against a production-sized copy. Record the slowest ones and fix them before the data moves.

Authorization gaps after rewriting AppSync rules

AppSync authorization rules, such as owner and group checks in the schema, do not carry over automatically. Supabase relies on row-level security policies in Postgres, and a table without policies can expose rows to any client holding the anon key. Write the access rules as a table of roles and expected results, then test each role against the policies with real requests: a user reading another user's rows, a non-admin writing to an admin table, and an anonymous request. Treat any unexpected allow as a blocker.

Single server with no recovery plan

A first self-hosted deployment is often one Docker host running every service and one Postgres instance. Self-hosted Supabase has no managed backups or point-in-time recovery, and PostgreSQL does not fail over on its own without external tooling. Decide in writing whether the production system needs a standby and automatic failover, who owns that tooling, and where backups are stored. Then run a restore drill into a clean environment and time it against the recovery target the business agreed to. A backup that has never been restored is not yet a backup.

Updates that change bundled services

Each self-hosted Supabase Docker release pins specific versions of Auth, PostgREST and Realtime, so pulling a new configuration changes running services. Some releases also carry one-way Storage database migrations, which cannot be reversed by rolling back the containers. Before any update, take a database backup, read the changelog for the release, test the update on a staging copy, and keep the previous configuration files so the team can restore the prior state. Because self-hosted Supabase is community-supported, plan who reviews these releases and who responds when one fails, either internally or through a contracted support arrangement.

How the move differs by Amplify footprint and starting point

A small app with one user pool, a handful of DynamoDB tables and modest S3 storage usually has a short list of moving parts. The main work is reshaping a few tables into Postgres, moving users, and rewriting the client SDK calls. Because the self-hosted Supabase project runs as a single project, a small team can usually run one instance for production and keep a separate instance for testing, without needing multi-project separation inside Studio.

  • User migration: Confirm whether Cognito password hashes can be exported. In most cases they cannot be listed, so plan for password resets or a login-time migration flow.
  • Table reshaping: Map each DynamoDB table to a Postgres table with explicit keys and types, and check access patterns before writing any schema.
  • Storage copy: Copy the S3 objects that the app references and verify object paths against database rows.
  • Parallel run: Use a single pilot and a short parallel run, with a clear date for turning off writes to Amplify.
  • Environments: Decide early whether test and production will be separate self-hosted instances.

Before cutover, confirm the exported row counts and object counts match the source, and that the client app works against the new endpoint.

What do teams ask before they plan an Amplify to Supabase move?

How much effort does an Amplify to self-hosted Supabase migration usually take?

Effort depends on the shape of the backend more than on the app's size. The main drivers are how many DynamoDB tables must be reshaped into Postgres tables, how many AppSync resolvers and Lambda functions need replacing with Postgres policies, Edge Functions or your own services, how many S3 buckets and objects must be copied, and how much client code has to change from the Amplify libraries to the Supabase client. The effort table on this page breaks these components down. No duration is given here because it varies with the backend, so ask any provider for a scope that lists each resource and its target before agreeing a timeline.

Can user passwords move from Cognito to Supabase without a reset?

Not directly from a standard export, because Cognito does not return password hashes through its ListUsers API. Moving users without forcing a reset therefore depends on a method that the team has to confirm with AWS and with the chosen migration path, such as a supported password export or a login-time migration where the old system verifies the password once and the new one stores it. If neither is possible, plan for a password reset flow or magic links for existing users. Confirm the approach in writing before cutover, because it determines how many users can sign in on day one.

Can our own engineers run this migration without outside help?

Yes, if the team has solid skills in PostgreSQL schema design, row-level security, authentication configuration and API work, and enough time to test each step. Self-hosted Supabase is community-supported through GitHub Discussions, GitHub Issues, Discord and Reddit, so your team would own upgrades, security patches and incident response, and enterprises can contact Supabase's Growth Team for other options. Many teams combine internal ownership with external help for the riskiest parts, such as the user move and the hardening work. DeployOpen plans, implements, hardens, backs up and documents self-hosted platforms in your own infrastructure under a written, fixed scope.

What does the client need to provide for an Amplify to Supabase project?

The work needs a few things from your side before it can start:

  • Access to the AWS accounts and environments that hold the Amplify backend, including DynamoDB, Cognito, AppSync, Lambda and S3
  • A named owner for each resource, such as user data, auth, files and functions, who can answer questions and approve changes
  • A set of test users and test data that reflect real account types, so the cutover can be checked
  • A decision on where Supabase will run, including the cloud account, data center or air-gapped network, and who will operate it

Identify the data residency requirements early, since they shape the hosting decision.

Is self-hosted Supabase the same product as Supabase Cloud?

No. Self-hosted Supabase runs as a single project, so Studio does not support multiple organizations or projects. Branching, advanced metrics, managed backups and point-in-time recovery, analytics and vector buckets, ETL and the Management API are not available when you self-host. Your team would need its own backup schedule, restore tests, monitoring and capacity planning. Confirm each feature your app uses against the self-hosting documentation before deciding, and plan replacements for any that matter to you.

When can we shut down the Amplify backend after cutover?

Decommission Amplify only after the rollback path is no longer needed. Keep the DynamoDB tables, Cognito user pool, AppSync API and S3 buckets available and read-only for a defined period after traffic moves, so you can return to them if a problem appears. Export a final snapshot of the data and the backend code, then remove resources in dependency order and check the AWS bill for leftover charges. Record the retirement steps as part of the migration evidence, because auditors and security teams often ask how data was disposed of.

Which AWS services do the data and user moves touch?

The data path starts with DynamoDB exports to S3 and ends in Postgres tables that match the new access model. The user path reads Cognito attributes through ListUsers, which excludes passwords, so auth and account data move separately. File objects in S3 are copied to Supabase Storage with their metadata and access rules rebuilt. Each path needs its own test plan and reconciliation check, such as row counts, user counts and file checksums, which the team should agree on before the first run.

How DeployOpen scopes, runs and supports an Amplify to Supabase migration

DeployOpen plans, implements, integrates, hardens, backs up, documents and supports self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks. For an Amplify to Supabase move, that means agreeing the scope in writing, rebuilding the data, auth and storage paths, and handing over a running, documented Supabase deployment.

How we scope

  • Inventory every Amplify resource: DynamoDB tables, Cognito user pools, AppSync resolvers, Lambda functions and S3 buckets.
  • Agree in writing which data, users and functions move, and which are retired or rewritten.
  • Confirm the target Supabase region and the hosting accounts that will hold the data before work starts.

How we build

  • Map DynamoDB item shapes to Postgres tables, keys and row-level access rules, then test the mapping on sample exports.
  • Plan the Cognito user move with the auth team, including how existing password hashes or forced resets are handled.
  • Rebuild resolver and function logic as Supabase features or Edge Functions, and test each path against the agreed scope.

How we hand over

  • Deliver the Supabase deployment, configuration, secret handling and runbooks inside your environment.
  • Document the data mapping, user migration steps, cutover checklist and rollback plan so your team can repeat them.
  • Walk your engineers through operations, backups and the upgrade procedure for the Docker configuration.

How we support

  • Ongoing support, upgrades and continuous security testing are available as a retainer after handover.
  • Plan patch windows for Supabase and PostgreSQL updates, and confirm backup restores before each upgrade.
  • Ask for a written support scope that names response expectations, since self-hosted Supabase is community-supported.

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.