The launch checklist gets all the attention. The reproduction packet gets you through bugs. But there is a third operational habit that AI-built apps need more than hand-built ones, and almost nobody sets it up: a backup that you have personally restored.
Not "a backup exists." Restored. By you. This week.
Why AI-built apps lose data differently
Hand-built apps lose data slowly, through bugs you wrote and understand. AI-built apps lose data fast, through changes you approved but did not fully read.
An agent asked to "fix the schema" may write a migration that drops and recreates a table. An agent asked to "clean up test data" may run its delete against the connection string it found in your environment — which is production, because your prototype only ever had one environment. An agent asked to "reset the local database" will happily do exactly that, and whether "local" meant what you thought depends on an env var you set three weeks ago.
None of these are model failures. They are operations failures: the app grew real users while its data practices stayed at the prototype stage. The agent just executes the gap faster than you would have.
Three habits close it: separate your environments, back up on a schedule, and — the step everyone skips — prove the restore.
Habit 1: make "production" a word that means something
Before backups matter, the agent needs to be physically unable to confuse environments.
- Two databases minimum. A development database the agent can destroy freely, and a production database it cannot reach from your laptop by default. Most hosted Postgres and serverless database providers make a second instance one click. The free tier of a second instance is cheaper than any restore.
- Different names that cannot be confused.
myapp-devandmyapp-prod, notdb1anddb2. When a migration log says what it touched, you should be able to tell at a glance. - The production connection string does not live in your local
.env. It lives in your host's environment settings and nowhere else. If the string is not on your machine, no local agent session can point at it by accident. When you genuinely need production access, take it deliberately and revoke it after. - Tell the agent the rule. One line in your project instructions: "There is a production database. Never run migrations, deletes, or resets against anything except the development database. Ask before any operation that touches data." Agents follow written constraints far more reliably than assumed ones.
Habit 2: backups on a schedule you did not have to remember
A backup that depends on you remembering is a backup that stops the week you get busy.
- Turn on your provider's automated backups first. Most managed databases include daily snapshots with point-in-time recovery on paid tiers. This is the highest-value checkbox in your dashboard. Find it, enable it, and write down the retention window — "we can go back seven days" is a sentence you want to be able to say from memory.
- Add one backup that leaves the provider. Provider snapshots protect you from your mistakes, not from account lockout, billing failures, or the provider's own bad day. A scheduled job that dumps the database and puts the file somewhere else — object storage on a different service is enough — covers the failure your provider cannot.
- Back up the things that are not the database. Uploaded files, environment variable values (in a password manager, not a text file), and the current deploy configuration. Teams have restored a database perfectly and still been down for a day because nobody knew the twelve env vars the app needed.
- Know what your backup does not cover. If you use third-party services for auth or payments, your users and subscriptions live in someone else's database. You are not backing those up; you are trusting the provider. That is usually fine — but the boundary should be a decision, not a surprise.
Habit 3: the restore drill
Here is the uncomfortable truth this post exists for: an untested backup fails at roughly the moment you need it. The file is empty because the dump job lost credentials months ago. The snapshot restores to a version your current schema cannot use. The restore takes four hours when you assumed four minutes. Every one of these is discovered either during a calm Tuesday drill or during the worst afternoon of your product's life.
The drill is thirty minutes:
- Take a fresh backup now. Not the scheduled one — prove the mechanism works on demand too.
- Restore it somewhere that is not production. A scratch database instance, or your development database if you can afford to overwrite it.
- Point a local copy of the app at the restored data. Sign in as a test user. Open the three screens that matter. The question is not "did the file load" — it is "does the app actually run against this data."
- Time it and write the number down. That number is your real recovery time. If it is unacceptable, you found out for free.
- Write the runbook while you do it. Five lines: where the backups live, the restore command, the env vars needed, the last drill date, the measured time. Put it in the repo. Future-you at 2 a.m. is the reader.
Then put a repeating event on your calendar: drill again every time the schema changes meaningfully, or monthly, whichever comes first.
The agent's role in all of this
This is one of the places where the agent that created the risk also does most of the setup work. All three habits are prompt-sized:
- "Write a script that dumps the production database to a timestamped file and uploads it to [bucket]. Add a scheduled job that runs it daily. Do not embed credentials; read them from the environment."
- "Add a restore script that takes a dump file and loads it into the development database, refusing to run if the target connection string contains 'prod'."
- "Write RUNBOOK.md documenting the backup location, restore steps, and required environment variables."
Review each one like you review any agent change that touches data — read the connection logic line by line, not the summary. Then run the drill yourself. The scripts are delegable; the proof is not.
The receipt
Like the launch proof ladder, this ends in an artifact you can point at. One line, dated, in your runbook, in this shape:
Restore drill [date] — full restore to scratch instance, app booted against restored data, [measured time], runbook updated.
If you cannot write that line for your product today, that is the highest-value half hour on your calendar this week. The agent made building fast. This is what keeps a bad Tuesday from deleting it.