How to back up your Lovable app (and test it)
7 July 2026· 3 min read · by Stackbastion
Lovable Cloud now includes daily backups. They’re kept for 14 days. That’s a real improvement over having nothing. But a backup you’ve never restored is a rumor, not a backup. And 14 days doesn’t cover everything. A bug can corrupt data quietly for three weeks before anyone notices. Here’s how to set up a backup you can actually trust, on your own Postgres instance.
Why daily snapshots aren’t the same as real backup
A daily snapshot only protects you against things you notice within 14 days. It also usually restores to last midnight, not to the exact moment before something went wrong. Point-in-time recovery, or PITR, fixes both problems. You keep a longer history. And you can restore to any second, not just to last night.
Step 1: set up continuous backup with PITR
If you run your own Postgres, pgBackRest is the standard tool for this. Here’s the pattern: a full backup on a schedule. Smaller backups in between. And a constant stream of write-ahead logs, so you can replay to any moment.
# One-time: initialize the backup repository
pgbackrest --stanza=main --repo1-path=/var/backups/pgbackrest stanza-create
# Weekly: full backup
pgbackrest --stanza=main --type=full backup
# Nightly: incremental backup
pgbackrest --stanza=main --type=incr backup
Add this line to postgresql.conf: archive_command = 'pgbackrest --stanza=main archive-push %p'. Now every log gets saved as it’s written, not just at backup time.
Step 2: get a copy off the server
A backup on the same machine as your database protects you against nothing. If that machine dies, the backup dies with it. Point pgBackRest’s storage at somewhere else: an S3-compatible bucket, or another off-site storage provider. Encrypt it while you’re there.
# repo1-cipher-type=aes-256-cbc in pgbackrest.conf, with a real passphrase
# repo1-path pointed at your off-server storage, not local disk
Step 3: the part everyone skips: actually test a restore
This step turns “I think we have backups” into “I know we have backups.” Restore to a separate, isolated copy. Never restore over your live database:
# Restore to a fresh, isolated data directory, never over the live one
pgbackrest --stanza=main --type=time \
"--target=2026-07-16 14:30:00" \
--pg1-path=/var/lib/postgresql/restore-test \
restore
Start Postgres against that restored copy. Run a query for a row you know should be there. Time the whole thing. That number is your real recovery time. Not a guess.
Step 4: set up dead-man’s-switch alerting
A backup that quietly stopped running three weeks ago is worse than no backup at all, because you think you’re covered. Have each successful backup ping a heartbeat monitor, a simple cron job hitting a health-check URL works fine. Send an alert if a heartbeat is missed for more than 24 hours.
Or, we do it for you
Setting this up correctly, restore drill included, is part of every Stackbastion plan. See what’s included. It’s also the core of our Full Production Rescue + Migration, if you’d rather have someone else do the migration.
FAQ
Do I need PITR if I already have daily snapshots?
Daily snapshots are better than nothing. But they only cover 14 days, and they only restore to midnight. PITR gives you a longer window and a more exact restore point.
How often should I actually run the restore test?
Do it once when you first set things up. Do it again any time you change your schema. After that, once a month is a fair pace for a small app.
What’s a reasonable recovery time for a small app?
There’s no single right answer. It depends what your users expect during an outage. Time your own restore first. Then decide if that number is good enough.
Get a free production audit
15-point check, scored report back in 48 hours, free either way.