I wanted to know three things about Supabase backups: what I actually have on each plan, what PITR really costs, and whether I can restore. So I read the docs and the dashboard, then ran a restore drill on a Free project and built a small check page. Everything is from my run on 2026-10-27. Prices change, so every number is dated.
How this was made: I wrote this with Claude's help: it drafted, and I ran every step, edited the text, and checked the results. The mistakes are mine. This is a personal learning project, not an official guide, and I don't work for Supabase.
The non-technical version (three kinds of backup, worst case, drills): https://medium.com/p/f9c4c58ef3bd
The code: https://github.com/tomozilla/backup-drill-en-demo
What I did and did not do
- Did: the drill on a Free project ($0): dump with the CLI, delete everything by accident, restore, count. I looked at a Pro project's backup pages read-only.
- Did not: press Restore (it makes the project unavailable), enable PITR, use Restore to new project, or test Storage files, Auth users or role passwords.
- Prices and conditions come from the docs and pricing page of 2026-10-27 (USD, no tax). I checked none of them against an invoice.
- A correction. In my earlier article on plans I wrote that PITR costs $100 a month. The docs say more: see below.
Three kinds of backup
1. Daily backups
The docs say Pro, Team and Enterprise projects are backed up daily, with 7 days (Pro), 14 days (Team) and 30 days (Enterprise) kept. On a Free project the dashboard says:
Free has no automatic backups. The docs recommend exporting regularly with the CLI db dump and keeping copies elsewhere.
On a Pro project (read-only):
Note the banner: Storage objects are not included.
The docs add two cautions:
- Passwords of custom roles are not stored, so after a restore you set them again.
- The project is unavailable while a restore runs, and the larger the database, the longer.
2. Point-in-time recovery (PITR)
From the docs:
- It combines a daily snapshot with a continuous record of changes (WAL), archived every two minutes by default: worst case about two minutes of loss.
- Price by retention: about $100 / month for 7 days, $200 for 14, $400 for 28.
- Condition: the project needs at least the Small compute add-on. Micro is not enough. That is what I left out earlier: PITR is the $100 plus the step from Micro ($10) to Small ($15).
- With PITR on, daily backups are no longer taken.
3. Your own copy
On Free, this is the main route. The drill below uses it.
The drill: take, break, restore, count
A backup that has never been restored is a hope. So I practised, on a Free project, with fake orders in their own schema backup_demo.
Before
Take
With the CLI logged in and linked (supabase login, supabase link):
supabase db dump --schema backup_demo -f backup/schema.sql
supabase db dump --schema backup_demo --data-only -f backup/data.sql
(scripts/backup.sh wraps both.) Two things I noticed:
- I never typed a database password. The CLI made a temporary login role for itself.
- The first attempt printed
Direct connection ... is unavailable because this environment does not support IPv6. Retrying via the IPv4 connection pooler.and then worked. The direct database host is IPv6-only on this plan, and my machine has no IPv6, so the CLI fell back by itself.
data.sql is plain SQL:
INSERT INTO "backup_demo"."orders" ("id", "customer", "item", "amount_usd", "status", "created_at") OVERRIDING SYSTEM VALUE VALUES
(1, 'Acme Demo', 'Starter kit', 49.00, 'paid', '2026-10-27 07:40:23.626218+00'),
... 5 rows ...
Break
I pretended to delete only the pending orders and forgot the WHERE: delete from backup_demo.orders;
Restore and count
I pasted data.sql into the SQL editor and ran it.
Five rows and $1,004.00 again. Two lessons:
- You are back to when the copy was taken. Anything written later is gone. How often you take copies decides how much you lose.
- Replaying the file into a table that still has rows fails on duplicate ids. I restored into an empty table.
Restore to a new project (read-only look)
The Pro project has a Restore to new project (BETA) tab that restores a backup into a new project rather than overwriting the current one.
I did not press anything. It looks handy for checking a backup without touching production, but I haven't tried it.
The backup check page
I put the rules into a small page: you enter the facts of each project, and it shows the worst-case loss and what is missing. It never connects to a project.
Worst case: about 2 minutes with PITR, up to 24 hours with daily backups, and on Free the time since your last manual dump (or "everything" if there never was one). Problems and warnings include Free with no dump, PITR on a compute smaller than Small, no restore test on record, and Storage files with no separate copy.
python3 -m http.server 8000 # from the repository root, then open http://localhost:8000/app/
node app/test.js # 18 checks
-
old-experiment(Free): no dump and files in Storage: problem, worst case "everything". -
customer-portal(Pro + PITR, Micro): problem, because PITR needs at least Small. -
billing-core(Team + PITR, Medium, tested, files backed up): OK, about 2 minutes.
The PITR add-ons total $300 a month ($100 for 7 days + $200 for 14 days). That excludes the compute upgrade.
Stumbles
"7 days old" tripped a 7-day limit
My first version warned that a dump taken 7 days earlier was "older than 7 days." The reason was the time of day: a date of 2026-10-20 compared with this afternoon is 7 days and a few hours. I now compare whole days. My tests used midnight timestamps, so they could not catch it. I only noticed when I ran the page.
Bad rows
A row with an unknown plan is skipped with a message, not dropped silently:
Limits
- You enter the facts, so stale input gives a stale verdict.
- "I tested a restore" is a claim the page cannot check.
- Not tested: dozens of projects, phone width, opening the page as a file.
What it costs
- The drill and the page: $0 (Free project).
- Daily backups: included in paid plans. PITR: about $100 / $200 / $400 a month for 7 / 14 / 28 days, plus at least the Small compute add-on.
- Storing your own copies elsewhere may cost something. Nothing here was checked against an invoice.
If I took this further
Not tried: reading the list of backups through the Management API so the page fills in the last backup time itself (it needs an access token, which I didn't want to handle), recording the result of each restore test (rows and totals), and an alert when a check is overdue.
Cleanup
I dropped backup_demo (sql/99_cleanup.sql).
Takeaways
- Three kinds: daily backups, PITR, your own copy. Free has only the last.
- Storage files are not in database backups.
- PITR needs Small compute or larger, and turns daily backups off.
- Practise a restore and count the rows. "Having a backup" is not "restoring it".
Next in this series: logins and audit trails instead of shared passwords.














Top comments (0)