Database Backups and Disaster Recovery for Solo SaaS

A practical guide for indie founders: what to back up, how to test restores, retention basics, and the minimum steps that keep a single mistake from ending the product.

Most solo founders treat database backups as a checkbox on a hosting dashboard. The real failure mode is not the absence of a backup file. It is discovering, during an incident, that the backup is incomplete, untested, or impossible to restore quickly enough to keep customers.

This is a minimal operating guide for a one-person SaaS. It assumes a typical Postgres or MySQL-backed product on a managed host. It is not a full disaster-recovery architecture for regulated industries.

Backups are only useful if you can restore them

A backup that has never been restored is an unverified claim. The questions that matter:

  • Can you get a working copy of the database in under an hour?
  • Does the restored data include everything required for the product to function (schema, data, and any large objects or extensions)?
  • Do you know the approximate point-in-time the backup covers?
  • Is the restore process written down somewhere other than your head?

If any answer is “I think so,” schedule a test restore before you need one.

What to include in a backup

For most micro-SaaS products, the critical set is:

  1. Primary application database — all tables, schemas, extensions, and sequences. For Postgres, a logical dump (pg_dump) or the host’s managed snapshot/PITR is usually sufficient early on.
  2. File storage — user uploads, generated reports, or assets if they live outside the database (S3-compatible buckets, local disks, etc.).
  3. Configuration that is not in git — environment variables, secret values, and feature flags that are not reproducible from the repo. Store these separately and encrypted; do not put raw secrets in the same dump as customer data if you can avoid it.
  4. Infrastructure definition — the minimal notes or IaC needed to recreate the host, database, and DNS. A short runbook beats a perfect Terraform file you have never applied.

You do not need to back up every log stream or metric. Focus on the data and config required to bring the product back for paying customers.

Managed hosts and the illusion of “we handle backups”

Many platforms (Railway, Render, Fly, Supabase, Neon, AWS RDS, and others) offer automated backups or point-in-time recovery. These are useful. They are not a complete plan.

Illustrative limitations you should verify for your provider:

  • Retention windows can be short (a few days) on lower tiers.
  • Some logical backups exclude certain extensions or large objects by default.
  • Point-in-time recovery may require a higher plan or manual steps.
  • Cross-region or off-platform copies are often optional and extra cost.
  • Restores may create a new instance rather than overwrite the existing one, which is safer but changes DNS or connection strings.

Read the current documentation for your host. Features change. The principle does not: know the recovery point objective (how much data you can afford to lose) and recovery time objective (how long customers can wait) that you are actually buying.

A practical retention approach

Early on, a simple layered approach works:

  • Frequent short-term: automated daily (or more frequent) backups retained for 7–14 days. This covers accidental deletes and bad migrations.
  • Weekly longer-term: one backup per week kept for 4–8 weeks. This covers slower corruption or the discovery of a bug that has been writing bad data.
  • Off-platform copy: at least one recent dump stored outside the primary host (another cloud bucket, or encrypted local storage you control). This protects against account lockout or host-level failure.

Label the retention policy in your runbook. When a customer asks “how far back can you go?”, you should be able to answer without guessing.

Testing a restore without drama

Do this on a non-production instance or a temporary database. Steps that work for most Postgres setups:

  1. Download or select a recent backup.
  2. Create a fresh empty database (or use the provider’s restore-to-new-instance flow).
  3. Restore the dump. Note how long it takes and any errors.
  4. Run a few application-level checks: can you log in with a test account, does a core query return expected rows, do sequences look sane?
  5. Delete the temporary instance when finished so you do not leave extra cost or data lying around.

Record the time and any friction. If the restore takes longer than your customers will tolerate, you have a product problem, not only a backup problem.

For MySQL/MariaDB the same idea applies with the host’s snapshot or mysqldump equivalent. The goal is identical: prove the path works.

Application-level habits that make recovery easier

  • Prefer backward-compatible migrations. A migration that cannot be rolled back cleanly makes a restore more likely.
  • Keep a short changelog of schema changes so you know which dump matches which application version.
  • Avoid storing critical state only in memory or only on ephemeral disks.
  • If you use background jobs or queues, know whether their state is in the primary database or a separate system that also needs recovery.
  • For multi-tenant products, confirm that a full restore brings every tenant’s data, and that you have a way to export a single tenant if needed for support or compliance.

When a backup is not enough

Backups do not protect against:

  • Logic bugs that have been writing incorrect data for weeks (you may need an older backup plus a repair script).
  • Credential compromise that also reaches your backup storage (use separate credentials and least-privilege access).
  • Ransomware or account takeover that deletes both live data and backups in the same account.
  • Legal or contractual requirements for longer retention or specific geographic storage.

For the last point, check what your customers or payment processor actually require. A micro-SaaS rarely needs the same retention as a bank, but enterprise buyers sometimes ask for documented recovery procedures.

A minimal checklist

Use this as a starting point and adapt it:

  • Automated backups are enabled on the primary database and file storage.
  • Retention covers at least a few days of frequent backups plus a few weeks of weekly ones.
  • At least one recent backup lives outside the primary hosting account.
  • Secrets and environment configuration are stored separately and can be reapplied.
  • A written restore procedure exists (even a short README).
  • You have performed at least one successful test restore in the last 90 days.
  • You know roughly how long a restore takes and what the maximum data loss window is.
  • Access to backup storage uses different credentials from the application runtime.

A one-weekend implementation plan

  1. Confirm what your current host already backs up and for how long. Note the gaps.
  2. Export one logical dump (or trigger a provider snapshot) and store it in a second location with encryption.
  3. Restore that dump into a temporary database and run basic sanity checks.
  4. Write a one-page runbook: where backups live, how to start a restore, how to point the app at the restored database, and who to tell if customers are affected.
  5. Add a calendar reminder to re-test in 60–90 days.

Database backups are unglamorous. They are also one of the few engineering tasks that can turn a recoverable mistake into a permanent one if ignored. A tested restore path is worth more than an elaborate monitoring dashboard you never look at during an incident.

Treat recovery as part of the product’s reliability, not as an afterthought you will handle “when you have time.”