Backups
How to restore a Supabase backup, and what breaks after
How to restore a Supabase backup from the dashboard or from a dump file, what the restore replaces, and why your app can still be broken when it finishes.

In short
- To restore a Supabase backup you either roll the project back from the dashboard, or replay a dump file into a project with psql. Which one is open to you was decided before today.
- Copy the database as it is now before you restore anything. A restore replaces the tables in the copy, so every row written since goes with them.
- The common outcome is a restore that succeeds and an app that is still broken, because your uploaded files and your login accounts were never in the database copy.
Something in your database is wrong, and for once you have a copy of it. Now you are looking at a button you have never pressed, on a project with real users in it, working out what it is about to do to them.
Here is the part that guide after guide leaves out. Almost every article on how to restore a Supabase backup stops at the moment the restore finishes, and that is where most of the trouble starts. The common outcome is not a restore that fails. It is one that succeeds and leaves the app broken anyway, because a database backup only ever held the database.
It helps to stop picturing this as putting your data back. A restore swaps your database for an older one, closer to exchanging a whole filing cabinet than to refiling one folder. Everything below follows from that.
How do I restore a Supabase backup?
Three routes, and which of them is open to you today was decided before today.
| Route | What it does | What it needs |
|---|---|---|
| The Supabase dashboard | Replaces the database in that project with a dated nightly copy you pick | A paid plan, and the copy still sitting inside your window |
| Point-in-time recovery | Rewinds the whole project to a minute you name | The PITR add-on, bought before the thing you are recovering from |
A dump file, replayed with psql | Loads the file into whichever project you point it at, new ones included | The file, and the database password for the target project |
The first two put your data back where it already was. The third is the only one that can put it somewhere else, which is what you need on the day the problem is your account rather than your data.
If you are not sure which of these you have, which Supabase plan you are on settles the first two and takes about two minutes to check.
Copy what you have now, before you restore anything
Take a copy of the database in its current broken state first. It is one command, and it is what makes every decision after it reversible.
pg_dump "postgresql://…your connection string…" \
--clean --if-exists --no-owner \
--file before-restore-2026-08-24.sql
There are two reasons, and people usually learn the second one afterwards.
The first is that a restore is a replacement. The tables in the copy come back exactly as they were, so every row written to them since goes too. A customer who signed up this morning is a row you are about to delete on purpose.
The second is that your broken database is still the only place some of your data exists. If the copy is from Tuesday and the damage happened on Thursday, everything created on Wednesday is sitting in front of you right now and nowhere else. Restore over it and it goes a second time, by your hand rather than by the accident.
While you work, turn off anything that writes new rows. The reasoning is the same as after any bad delete: the gap between the copy and now gets more expensive the longer the app keeps filling it.
Restoring from the Supabase dashboard
This replaces the database in your project with the copy you choose, and the project is unavailable while it runs.
Open the project your app talks to, find Database and then Backups, and pick the dated copy you want. Read the exact steps in Supabase's own backup documentation, because the dashboard gets rearranged and this page will not notice when it does.
How long it takes depends on the size of your database, which is Supabase's own answer. Put up a maintenance notice before you begin.
Point-in-time recovery is the same operation with a finer dial. Instead of picking last night you name a minute, and the project rewinds to it. Supabase describes it as destructive, which is the right word for it. Their troubleshooting notes also say a point-in-time restore cannot start until existing replication slots and subscriptions are removed, so if anything in your app streams database changes as they happen, that is a step to take first rather than an error to hit halfway through.
Neither route can put your data into a different project. Both act on the project you are standing in, which means both are unavailable on the day the thing that went wrong is your access to the account.
Restoring a dump file with psql
You point psql at a project and replay the file into it. That project can be
the one you had, or a brand new one on an account you opened this morning.
psql -d "postgresql://…the target project's connection string…" \
--variable ON_ERROR_STOP=1 \
--single-transaction \
--file backup-2026-08-09.sql
Two of those flags are worth understanding, because psql's default behaviour is the surprising one.
ON_ERROR_STOP=1 stops at the first error. Leave it out and psql reads the
error, prints it, and carries on to the next line, so a file that failed on
line 400 of 30,000 still ends at a prompt that looks like success, over a
database missing everything after that line. --single-transaction wraps the
whole file in one operation, so a failure leaves the database as it was instead
of half changed.
Then the credential, which is where people get stuck. Replaying a backup means
writing, so it needs something that can write. An anon key will not do it and
neither will a read-only one. What psql wants is the database password for
the target project, which lives in your Supabase project settings under
Database.
What comes back depends on what is in the file, and that was settled when the
dump was taken. Your login accounts are the part to check before you rely
on it. They live in a schema called auth alongside the hashed passwords, and
Supabase documents
moving them between projects
as a job with its own steps. If you are restoring into a new project and you
want people to sign in with the password they already have, read that page
before you start.
And a new project has a new URL and new keys. Your app is still pointed at the old one until you change it, which is the first line of the next section.
It restored, and the app is still broken
This is the ordinary outcome. It is almost always one of five things, and the first one takes a minute.
| What you see | What actually happened | What to do |
|---|---|---|
| The app loads and every list is empty | It is still talking to the old project | Put the new project's URL and publishable key into your app's settings, then redeploy |
| Images, avatars and uploads are gone | Files live in Storage, outside the database. The rows you restored hold only the path to each file | Restore your files from their own copy. No database backup on any route contains them |
| Nobody can sign in | Login accounts live in the auth schema, and whether they were in the file depends on how the dump was taken | Follow Supabase's auth migration guide, or restore again from a copy that includes that schema |
| Pages read fine and saving anything fails | The database came back readable and not writable | Create a row through the app before you call it done. The paragraph below has the detail |
| One feature is broken, its table is fine | Edge functions live in your repository, outside the database | Redeploy them from your builder or your repo |
The fourth one deserves the attention. Permission to read and permission to write are granted separately, and a restore can land one and miss the other. So the pages fill with your data, everything looks recovered, and then the first person to submit a form gets an error. Looking at the app will never show you this, because looking is reading.
How to tell whether the restore actually worked
Sign in, find a row you can name, and then write one. In that order, and the last one is the check that counts.
- Sign in through the app the way a user would, rather than opening the Supabase table editor. That tests the app, the connection and the login accounts in one go.
- Find a row you remember. A specific order, a named customer, the last thing you added before it broke. "The data looks like it is there" is a feeling; a row you can name is a check.
- Compare a count against what you expected. Open your biggest table in the Supabase editor and read the number of rows. A restore that stopped partway usually shows up here as a number that is too small.
- Then write something. Create a row the way a user does: place a test order, save a profile, post a comment. This is the check that fails when the other three pass, and it is the only thing that proves the restore finished.
- Open something a user uploaded. If your app has images or attachments, click one. Whether your files came back is a separate question from whether your rows did.
What to do right now
What to do
- Copy the database as it is now, before you restore anything. It is one
pg_dump, and it is what makes the next decision reversible. - Turn off anything that writes new rows while you work, because a restore deletes whatever arrived after the copy was taken.
- Match the route to the problem. A dashboard restore fixes your data; only a dump file replayed with
psqlcan move your data to a new project. - If you are using
psql, setON_ERROR_STOP=1. A restore that quietly gave up partway looks exactly like one that worked. - Check the restore by writing, not by reading. Sign in, find a row you can name, then create one through the app.
- Treat your uploaded files and your login accounts as separate jobs. Neither is finished when the database restore is.
Before you close this tab, find out whether you have anything to restore from at all, and where it is. That one answer decides which half of this article you will ever need. The 10-minute security checklist covers it alongside the other things worth confirming on a newly launched app, and the Supabase safety guide goes through what tends to be left open.
What Reeve Care does on the day you restore
The copy already exists, it has already been read back and checked, and it sits outside your Supabase account. That turns the hour above into a choice of which copy, and a button.
Four things it changes about this article specifically.
The copy has been verified before you need it. Every backup is read back and counted against what went in, and the date shown in your dashboard is the last copy that passed rather than the last one attempted. The half-finished restore this article warns about is a problem we find on an ordinary afternoon, before it is yours.
The safety copy is not a step you have to remember. Pressing restore takes a fresh copy of the current state first, so the restore itself can be undone.
Your uploaded files come back too, once you connect your Storage buckets. That is the row in the table above with no good answer otherwise.
The database key we hold can only read. A restore has to write, so it asks for your database password each time and keeps none of it. The optional key for your files can write, because Supabase issues no read-only key for Storage, and the page where you hand it over says so before you do.
The limits belong in the same breath, because you should know them before you pay rather than during an outage:
- It works with Supabase and nothing else today.
- You restore to a copy that exists, not to any minute you name. Worst case you lose one interval, which is up to a night on the entry plan and shorter on the two above it.
- Login accounts are never touched. Nobody is signed out, deleted, or brought back.
Keep your Supabase backups switched on either way. Two copies in two places is the whole idea, and the cheaper of the two is already in your plan. What each Care plan covers is on the homepage.
If you would rather not pay for any of it, everything in this article still
works. A pg_dump on a schedule you genuinely keep, held somewhere that losing
your Supabase account would not also take, plus one practice restore a quarter,
gets you most of the way there.
The three routes and what each one misses
covers that without a sales pitch.
The whole cycle is drawn out step by step on the Supabase backups page: the copy leaving Supabase, the check that follows it, and the button that puts it back.
FAQ
How do I restore a Supabase backup?
There are three routes. From the dashboard you pick a dated nightly copy and Supabase replaces that project database with it, which needs a paid plan. Point-in-time recovery rewinds the whole project to a minute you name, which needs the PITR add-on bought in advance. Or you replay a dump file into a project yourself with psql, which is the only route that can put your data into a different project on a different account. Before any of them, take a copy of the database as it is now.
Does restoring a backup delete the data added since it was taken?
Yes. A restore is a replacement rather than a merge: the tables in the copy come back exactly as they were at that moment, and everything written to them afterwards goes. That includes rows that were perfectly fine. It is the reason to stop your app writing before you start, and the reason to keep a copy of the current state so you can put the good newer rows back on top afterwards if you decide you want them.
My restore finished but the images in my app are missing. Why?
Because your files were never in the backup. Supabase Storage sits outside your Postgres database, so a database backup holds the row that points at each file and none of the files themselves. Restoring gives you a table full of links to things that are no longer there, or that are in a project you are no longer using. Storage has to be copied and restored separately, whichever backup route you took.
Can I restore a Supabase backup into a different project?
Only with a dump file you hold. The dashboard restore and point-in-time recovery both act on the project you are standing in, so neither helps on the day the problem is that you cannot get into the account at all. A pg_dump file replayed with psql goes into whichever project you point it at, including a brand new one on a new account. That is the difference the day it matters.
Will my users have to sign up again after a restore?
That depends on whether your login accounts were in the copy. They live in a database schema called auth, along with the hashed passwords, and Supabase documents moving them between projects as a job with its own steps rather than as something that rides along with your tables. If you are restoring into a new project, read that guide before you start. A restore inside the same project usually leaves sign-in alone.
How long does a Supabase restore take?
Supabase says it depends on the size of your database and how much data has to be processed, which is the honest answer and not a helpful one when you are waiting. Assume the project is unavailable for the duration and put up a maintenance notice before you begin. Their troubleshooting notes also say a point-in-time restore cannot start until existing replication slots and subscriptions are removed, so check that first if anything in your app streams database changes.