Guides / Backups

An AI agent deleted a production database in nine seconds. Could yours come back?

In late April 2026, a coding agent working on a routine task found an over-scoped platform token, issued one API call, and erased a company's production database, and the backups with it, because the backups lived on the same volume as the data. The newest copy that survived was three months old. This guide is the backup setup that makes that story survivable: what Supabase and Firebase actually give you on each plan, the exact commands for copies that share no fate with production, and how to keep AI agents away from the delete button.

Nine seconds, one API call, three months of data.

The incident is worth thirty seconds of your attention because every part of it is ordinary. A Cursor agent was doing routine staging work for PocketOS, a software company serving car-rental businesses. It hit a credential mismatch, went looking, and found a Railway API token in an unrelated file. The token had been created for domain management but was scoped for any operation. The agent used it to send a single API call, a volumeDelete mutation, and nine seconds later the production database was gone. So were the backups, because Railway stored volume-level backups inside the volume that was deleted. The newest recoverable copy was three months old, staff spent the weekend rebuilding customer records from Stripe payment histories and email logs, and it took more than thirty hours to get a clear answer on recovery. The founder's advice afterwards: evaluate whether your platform's volume backups are the only copy of your data. They should not be.

Two separate failures had to line up. An agent held a credential that could destroy production, and the backups shared fate with the thing they were backing up. Most vibe-coded apps have both problems today, and the second one is often worse than PocketOS had: on Supabase's free plan there are no automated backups at all. Fixing both takes an afternoon.

Railway itself has since shipped the right pattern: its point-in-time recovery for Postgres (July 2026 docs) archives every write-ahead-log segment to a separate storage bucket, off the volume, and restores into a brand-new service without touching the source. Its plain volume backups still carry the documented caveat "Wiping a volume deletes all backups". The lesson generalises to every platform: know which kind you have.

Supabase: what each plan actually gives you.

Supabase backs up Pro, Team, and Enterprise projects daily: Pro keeps 7 days, Team keeps 14, Enterprise up to 30. The free plan gets none, and Supabase's own documentation says free projects should export regularly with the CLI and keep off-site copies. Free projects are also paused after a week of inactivity. If your vibe-coded app runs on free-tier Supabase, and most Lovable and Bolt builds start there, your current backup count is zero.

Point-in-time recovery is the upgrade: instead of restoring to last night, you restore to any second you choose. It is an add-on for paid plans, needs at least the Small compute size, replaces the daily-backup mechanism, and starts around USD 100 per month for a 7-day window. For most early apps, daily backups plus an off-site dump are enough; buy PITR when an hour of lost writes would cost real money.

Three gotchas worth knowing before the bad day: database backups cover the database only, so files in Storage buckets are not included (only their metadata); custom-role passwords are not stored and need resetting after a restore; and deleting a project permanently deletes its backups with it.

The off-site copy costs nothing but a cron job. With the Supabase CLI installed, these three commands dump roles, schema, and data (the official backup sequence):

supabase db dump --db-url "$SUPABASE_DB_URL" -f roles.sql --role-only
supabase db dump --db-url "$SUPABASE_DB_URL" -f schema.sql
supabase db dump --db-url "$SUPABASE_DB_URL" -f data.sql --use-copy --data-only

Run them nightly from a GitHub Action or any machine you control, and ship the files somewhere that is not Supabase: object storage, an encrypted disk, anywhere with a different login. Restoring into a fresh project is one command:

psql \
  --single-transaction \
  --variable ON_ERROR_STOP=1 \
  --file roles.sql \
  --file schema.sql \
  --command 'SET session_replication_role = replica' \
  --file data.sql \
  --dbname "$NEW_PROJECT_DB_URL"

Note what that gives you: a rehearsable, non-destructive restore. The copy lands in a new project, production is never touched, and you can prove the backup works without betting anything on it.

Firebase: scheduled backups, exports, and minute-level recovery.

Firestore has a managed backup scheduler that most AI-built apps never turn on. It needs billing enabled (the Blaze plan), and then two commands buy you daily and weekly copies:

gcloud firestore backups schedules create --database='(default)' \
  --recurrence=daily --retention=7d
gcloud firestore backups schedules create --database='(default)' \
  --recurrence=weekly --retention=14w --day-of-week=SUN

Retention runs to a maximum of 14 weeks, and restores always land in a new database, never over your live one:

gcloud firestore backups list --format="table(name, database, state)"
gcloud firestore databases restore \
  --source-backup=projects/PROJECT_ID/locations/LOCATION/backups/BACKUP_ID \
  --destination-database='restore-test'

One caveat straight from the PocketOS playbook: Google keeps each backup in the same location as the source database. That protects you from deletion and corruption, which is the realistic threat for a vibe-coded app, but for a copy with a fully separate fate, add a periodic export to a Cloud Storage bucket (gcloud firestore export gs://your-backup-bucket), ideally in another region. Budget note: an export costs one document read per document exported, and those reads do not show in the console's usage graphs. Firestore also offers point-in-time recovery: off by default, a 7-day window once enabled, and one-minute granularity, coarser than Supabase's per-second restore but enough to undo yesterday's bad migration. It is not retroactive, so enabling it today is what makes it useful next month.

If you are on the Realtime Database rather than Firestore, Blaze projects can switch on automated daily backups to a Cloud Storage bucket in the console: data and security rules land as compressed JSON, with an optional 30-day auto-delete lifecycle.

The three rules, whatever your stack.

  1. One copy with a separate fate. A backup that the same credential, the same volume, or the same billing account can destroy is a convenience, not a backup. At least one nightly copy belongs off the platform that runs production: a dump in object storage, a different account, a different login. This is the single change that would have saved PocketOS three months of data.
  2. Shrink the blast radius of your tools. The agent did not break in; it used a token it was given. Audit what your coding tools can reach: no production credentials in the repository or the development environment, platform API tokens scoped to the narrowest role available, and destructive operations behind an account the agent simply does not hold. If an AI tool can touch production at all, assume that one day, confidently and politely, it will.
  3. Rehearse the restore. Supabase restores into a new project; Firestore restores into a new database. Both platforms have made restore drills non-destructive, so run one: restore last night's copy, point a local build at it, click around. Once a quarter is our recommendation, and always before a risky migration. The drill also tells you your real recovery time while nobody is waiting on it.
A backup you have never restored is a hypothesis Every failed-recovery story has the same shape: the backups existed, and the first time anyone tried to restore one was the day everything depended on it. The restore drill is the cheapest insurance in this entire guide series: it costs an hour and a temporary project, and it converts "we should be fine" into "we tested it".

Questions

Questions founders ask.

Does the Supabase free plan include backups?

No. Automated daily backups start on the Pro plan (7 days retention; Team keeps 14). Supabase's own documentation recommends that free-tier projects export regularly using the CLI db dump command and keep off-site copies. Free projects are also paused after a week of inactivity. If your app runs on free-tier Supabase and you have never run a dump, you currently have no backup.

What is point-in-time recovery, and do I need it?

Daily backups restore you to last night; point-in-time recovery restores you to a moment you choose, because the database's write-ahead log is archived continuously. On Supabase it is a paid add-on with per-second granularity, starting around USD 100 per month plus a compute minimum. Firestore's version is off by default, keeps 7 days, and restores to the minute. Start with daily backups plus an off-site dump; buy PITR when an hour of lost writes costs more than the subscription.

How do I stop an AI coding agent from deleting my database?

Assume it will try something destructive eventually, and make that attempt harmless. Keep production credentials out of the repository and the development environment the agent works in, scope platform API tokens to the narrowest role the task needs, and keep at least one backup somewhere the agent's credentials cannot reach. The PocketOS deletion needed an over-scoped token lying in a file and backups on the same volume; remove either condition and the story ends differently.

Are my platform's built-in volume backups enough?

Check one thing: can the credential or action that destroys the data also destroy the backup? Railway's documentation still notes that wiping a volume deletes all its backups, which is exactly what happened to PocketOS, though its newer Postgres point-in-time recovery ships write-ahead logs to a separate bucket. Whatever the platform, keep one nightly copy with a genuinely separate fate: different storage, different credentials.

How often should I test restoring a backup?

Quarterly, and before any risky migration, is our recommendation; neither Supabase nor Google mandates a schedule. Both platforms restore into a new project or database rather than over production, so a drill risks nothing: restore last night's copy, point a local build at it, and confirm the data is really there. You also learn your true recovery time on a calm day instead of during the incident.

Recovery is a production concern

Know your recovery story before you need it.

A production-readiness review covers the whole chain: where your data lives, what can destroy it, whether your backups would survive the same event, and a restore path you have actually seen work, ranked alongside every other fix.