On Render’s Free compute plan a Postgres database gets no logical backups and no recovery, and deleting a Supabase project permanently removes its backups. A database backup checklist for startups closes both gaps in four lines: know what your provider keeps on your plan, set the retention, keep an encrypted copy in a second account, and restore it once.

The database backup checklist for startups: what your provider keeps, and what you add

A database backup checklist for a startup is four lines: know what the provider keeps on your plan and for how long, set the retention the business can live with, keep an encrypted copy in a bucket in a second account, and restore it once into an isolated database with the date written down.

This is the backup check in the data consistency checklist for SaaS, which lists the other database checks a live app needs.

The first-hour article linked in the next section already has a platform table, “What each platform actually gives you”, with default backups and point-in-time recovery for Supabase, Railway, Neon and others. This page does not repeat its recovery column. The table below adds what that one leaves out: where the copy lives, plus rows for Render and Amazon RDS.

HostPlanWhat is keptHow longWhere the copy lives
SupabasePro, Team and Enterprise; on the free tier Supabase recommends a CLI export and off-site backups of your ownDaily backups, listed under Database > BackupsPro 7 days, Team 14 days, Enterprise up to 30 daysDeleting the project permanently removes “any backups stored in S3”
NeonFree, Launch and ScaleChange history (WAL records) that instant restore reads fromFree 6 hours (capped at 1 GB of history); Launch and Scale 1 day by default, up to 7 and 30 daysKept for the project’s branches; a deleted project can be recovered within 7 days
RailwayPro and Enterprise, per Railway’s pricing page (not Free or Hobby); you pick schedules per volumeVolume backups on daily, weekly or monthly schedulesDaily kept 6 days, weekly 27 days, monthly 89 daysWith the volume: “Wiping a volume deletes all backups”, and backups can only be restored into the same project and environment
RenderPaid databases only; nothing on the Free compute planContinuous backups of paid databases, plus logical backups (exports) you triggerRecovery window: Hobby past 3 days, Pro or higher past 7 days; logical backups kept seven daysNot stated in Render’s docs; exports can be downloaded
Amazon RDSAny DB instance with a retention above 0Automated backups: a storage volume snapshot of the whole DB instance1 day by default from the API or CLI, 7 days from the console; settable from 0 to 35 daysAmazon S3; deleted with the instance unless you choose “Retain automated backups”

Every cell comes from the host’s own page, read on 28 September 2026: Supabase’s backups page, Neon’s history window page (with Neon’s projects page for deletion), Railway’s volume backups page (with Railway’s pricing page for plans), Render’s Postgres backups page and Amazon RDS automated backups.

Read the last column twice. A backup that goes when the project or the volume goes is not a second copy of your data. Where a host’s docs do not say, as Render’s do not, ask the host before you count on it.

That leaves three lines the host does not do for you, and they are the part of data protection a SaaS owner controls: the retention you choose, the copy in a second account, and the restore. To manage your own SaaS data backup, the rest of this page takes them in order.

The phrase backups for SaaS usually means something else: backing up the SaaS tools a company uses, such as Microsoft 365 or GitHub. The cloud backup services for startups that sell that kind of SaaS backup and recovery are a different product from the database backup on this page.

If Postgres runs on your own server instead of a managed host, keep the same checklist; the best practices for server backup solutions differ in one place only, because your own scheduled dump stands in for the host’s copy.

The host table above and the policy block further down are a simple template for this backup checklist, with nothing to download. The techniques are simple on purpose and the setup is easy: the backup checklist starts with reading one page of your host’s docs.

Supabase backups, in one paragraph

Supabase’s row in the table above is all this page says about it. Supabase backups: plans, limits and a restore drill covers the backup methods, the free-plan dump, Storage buckets, point-in-time recovery and a timed restore.

What goes wrong without it

Each row below is a way a small app ends up with no backup of the production database at the moment it needs one.

SituationWhat is lostThe checklist line that prevents it
A free tier plan has no backups, and a migration drops a columnThe column’s data: there is nothing to restore fromKnow what the provider keeps
The only backup lives with the project, and someone deletes the Supabase project or wipes the Railway volumeDeleting the project or wiping the volume deletes the backups tooKeep a copy in a second account
The retention was shorter than the time it took to notice a bad writeEvery backup still kept was taken after the bad write, so each one carries the damageSet the retention
The backup was never restoredNothing yet, but nobody knows whether the file loadsRestore it once

A founder runs a small app’s Postgres database on Render’s Free compute plan and has never checked what the plan keeps. A migration drops the wrong column. Render “does not create logical backups for databases on the Free compute plan” and “does not provide recovery capabilities for databases on the Free compute plan”, so there is nothing to restore from. What the plan keeps is a fact to look up before it is needed, and when the answer is none, a dump in a second account is the only copy there is.

Secrets leak too: 6 of the 21 third-party apps I audited in June and July 2026 shipped a real secret, and the Data Integrity & Safety pillar averages 51.6 out of 100 across the 20 of those apps scored on it. That is a selected set of apps I audited, not a random sample, so neither figure is a rate for AI-built apps in general. In my reading, whether a leaked key can reach the backups depends on each host’s credential boundaries, which the restore-drill article linked in the verify section works through.

If the deletion has already happened, the first hour after deleting the production database covers what to do now, including whether to restore over production.

How to do it: retention, the off-site copy, the policy

Backing up a small SaaS database takes five decisions, made in order: learn the words, set the retention, schedule an encrypted copy to a second account, protect the file with a passphrase, and write the policy so someone else can check it.

What is data backup and recovery? Full, incremental and 3-2-1 in plain English

Data backup and recovery means keeping copies of the database and bringing one back when the original is lost or damaged. The PostgreSQL manual names three approaches: an SQL dump, a file system level backup, and continuous archiving, which pairs a base backup with the write-ahead log so the database can be recovered to a chosen moment.

In practice, backup works in two halves: something copies the data on a schedule, such as the host’s nightly backup or your own pg_dump, and a restore brings one chosen copy back into a database you can use.

The manual’s continuous archiving section uses three terms. A base backup is the full copy, most easily made with the pg_basebackup tool. An incremental backup, taken with pg_basebackup’s --incremental option, replaces some data files with smaller files holding only the blocks changed since an earlier backup, and needs every earlier backup it builds on at restore time. Point-in-time recovery replays the archived write-ahead log to restore the database to any moment since the base backup. pg_basebackup gained incremental backups in PostgreSQL 17, and the manual’s advice for a small database is that “it’s simpler to ignore the existence of incremental backups and simply take full backups, which are simpler to manage.”

Beyond those three types of backups, two more words come up on a managed host: a snapshot is the host’s own backup, and a dump is a file you make yourself with pg_dump. The two types of cloud backup methods that matter for a small SaaS follow from that: the host’s managed backups, and your own export to storage you control.

The 3-2-1 rule, in CISA’s fact sheet, reads: “Implement the NIST 3-2-1 rule: 3) Keep three copies: one primary and two backups; 2) Keep the backups on two different media types; 1) Store one copy offsite.” As a backup and recovery example for one app, the three copies are the live database, the host’s backups and the encrypted dump in a second account’s bucket; in my reading the bucket in the second account is the offsite copy, though not a second media type where the host also keeps its backups in Amazon S3, as Supabase’s and Amazon RDS’s docs say they do.

Recovery point and recovery time objectives, and how a small app picks them, belong to the restore-drill article linked in the verify section. Of the backup and recovery strategies you could run, a good backup strategy for a small SaaS is the four-line checklist at the top of this page.

What retention to set, and where

The backup retention a small SaaS needs is my working rule, not a standard: about 30 days of daily copies, about 12 weekly and about 12 monthly, plus point-in-time recovery while the app takes payments if the host sells it. Set it in two places: the host’s plan and the bucket’s lifecycle rule.

  1. 01 Keep a daily copy for about 30 days
  2. 02 Keep one weekly copy for about 12 weeks
  3. 03 Keep one monthly copy for about 12 months
  4. 04 Turn on point-in-time recovery while the app takes payments, if your host sells it

The host’s copies follow the host’s own setting: Supabase’s plan, Neon’s history window under Settings > Postgres, Railway’s schedules on each volume, Render’s workspace plan, and the retention period on an RDS instance. Where a host’s own window is shorter than the rule, as Railway’s 6-day dailies are, the bucket carries the rest.

The dumps are kept by the bucket’s lifecycle rule. AWS’s page on S3 Lifecycle rules describes expiration actions as rules that “define when objects expire. Amazon S3 deletes expired objects on your behalf.” To set a backup retention policy for Postgres, then, a managed host means the plan setting, and your own server means the dump schedule plus the bucket rule.

On AWS the same decision takes the form of a backup plan, which AWS defines as “a policy expression that defines when and how you want to back up your AWS resources”.

The off-site copy: a cron dump, an AWS Backup vault or an Azure vault

The off-site copy is a scheduled job: dump the database with pg_dump, encrypt the file, upload it to a versioned bucket in a second cloud account, and log its size and checksum. An AWS Backup vault or an Azure Backup vault does the same job as a managed service for a database already on that cloud.

  1. 01 Schedule the job: a crontab line on a small VM, a GitHub Actions schedule, or your platform's own cron, on a runner that can reach the database connection string
  2. 02 Dump with pg_dump --format=custom, using a pg_dump at least as new as the server's major version
  3. 03 Encrypt the file with a passphrase before it leaves the job
  4. 04 Record the file's size and its SHA-256 checksum
  5. 05 Upload with aws s3 cp to a bucket in a second cloud account, with versioning on and a lifecycle rule that also expires noncurrent versions, using credentials that can put objects and nothing more
  6. 06 Post the size and checksum to the job log, so a missing or tiny file is noticed the next morning

The put-only credentials in step 5 are my working rule: a job that can only add files cannot delete the history it exists to protect.

A backup crontab line has five time and date fields (minute, hour, day of month, month, day of week) and then the command, and cron turns an unescaped % in that command into a newline, which is one reason to keep the job in a script file and call the file. A GitHub Actions schedule uses POSIX cron syntax and runs in UTC by default; GitHub also says the schedule event can be delayed at busy times, some queued jobs may be dropped under high load, and in a public repository scheduled workflows are disabled after 60 days with no repository activity. Step 6 is there for exactly those nights. For Supabase, which connection string to use from a CI runner is covered in the Supabase backup article linked above.

The PostgreSQL manual describes the custom format as “a custom-format archive suitable for input into pg_restore” that is “also compressed by default”, and warns that “pg_dump cannot dump from PostgreSQL servers newer than its own major version; it will refuse to even try”. Versioning on the bucket means a deleted file gets a delete marker instead of being removed, and an overwritten one keeps its previous version. If the bucket also has an expiration rule, AWS says that to keep the same permanent delete behavior once versioning is on, “you must add a noncurrent expiration configuration.”

The job as one script, with placeholders in angle brackets:

set -e
F="db-$(date -u +%F).dump"
pg_dump --format=custom --file="$F" "<DATABASE_URL>"
gpg --batch --pinentry-mode loopback --passphrase-file "<passphrase-file>" --symmetric --output "$F.gpg" "$F"
rm "$F"
sha256sum "$F.gpg" > "$F.gpg.sha256"
ls -l "$F.gpg"; cat "$F.gpg.sha256"
aws s3 cp "$F.gpg" "s3://<backup-bucket>/daily/$F.gpg"
aws s3 cp "$F.gpg.sha256" "s3://<backup-bucket>/daily/$F.gpg.sha256"

set -e stops the script at the first failed command, so a failed dump is never encrypted and uploaded as if it were good, and the unencrypted dump is deleted once the encrypted file exists.

If the database already runs on AWS, AWS Backup vaults are the managed option; a vault is, in AWS’s words, “a container that stores and organizes your backups”, created with the AWS KMS key “that encrypts some of the backups placed in this vault”. In Terraform, AWS Backup is set up with the aws_backup_plan resource, whose rule names a target_vault_name, a cron schedule and a lifecycle block with delete_after for the retention. On Azure, the choice between a Backup vault and a Recovery Services vault follows the workload: Azure’s Backup vault overview lists Azure Database for PostgreSQL servers among what a Backup vault holds, while a Recovery Services vault holds backup data for services such as IaaS VMs and SQL Server in Azure VMs. In my reading, either vault is worth it only when the database already runs on that cloud; for a database on Supabase, Neon, Railway or Render, the script above is the shorter route.

How to GPG encrypt the backup file with a password

GPG encrypts a backup file with a password through its symmetric mode: with --passphrase-file it reads the passphrase from a file when run with --batch, so the scheduled job needs no one at the keyboard. The passphrase lives in the secrets store, where the restore runbook can reach it.

The dump holds every customer’s data, so it is encrypted before it leaves the job. The GnuPG manual says --symmetric will “Encrypt with a symmetric cipher using a passphrase”, with AES-256 as the default cipher. Two conditions come with --passphrase-file: only the first line of the file is read, and since version 2.1 --pinentry-mode loopback has to be set as well as --batch. The manual’s caution applies too: a passphrase stored in a file “is of questionable security if other users can read this file”, so only the job’s user should be able to read it.

gpg --batch --pinentry-mode loopback --passphrase-file "<passphrase-file>" --symmetric --output backup.dump.gpg backup.dump
gpg --batch --pinentry-mode loopback --passphrase-file "<passphrase-file>" --decrypt --output check.dump backup.dump.gpg

Run the second line on another machine, not the job’s: gpg caches the passphrase used for symmetric encryption, so a decrypt on the same machine “may not require that the user needs to enter the passphrase” and proves less. Never put the passphrase in the same bucket as the file. The cloud’s own key service on the bucket is the other route; encryption beyond this one file is covered in encryption at rest for a SaaS.

A backup and recovery policy a reviewer can read

A written backup and recovery policy fits on one page and eight lines: what is backed up, how often, where each copy lives and in whose account, how long each is kept, how it is encrypted and who holds the key, the recovery point and recovery time accepted, the rehearsal and its evidence, and the owner.

Copy the block below as the template for a database backup policy and fill in the angle brackets; there is no download.

1. What is backed up: the production database, and the files in storage
2. How often: <host backup schedule>; a nightly encrypted dump
3. Where each copy lives: host backups in <host account>; dumps in <bucket> in <second cloud account>
4. How long: daily copies about 30 days, weekly about 12 weeks, monthly about 12 months
5. Encryption: GPG symmetric (AES-256 by default); passphrase in <secrets store>, held by <name>
6. Accepted loss and downtime: recovery point <hours>, recovery time <hours>
7. Restore rehearsal: into an isolated database every <period>; evidence kept in <location>
8. Owner: <name>, reviewed every <period>

Line 1 names the files because a database backup may leave them out: Supabase’s backups exclude objects stored through the Storage API. When a reviewer asks for the data backup and recovery policy, this block, filled in and dated, is what you send. It also answers the backup questions in security questionnaire examples, and the disaster recovery checklist for SaaS is the plan that sits above it.

How to verify it

A backup is verified five ways: the host lists a backup from the last day, the off-site bucket holds last night’s file with the checksum the job logged, the file decrypts, it restores into an isolated database, and records you know come back unchanged. Keep the listing, the log line and the restore output, dated.

  1. 01 The host lists a backup from the last day. Evidence: the listing with its date
  2. 02 The off-site bucket holds last night's file, its size is in the usual range, and its checksum matches the one the job logged. Evidence: the bucket listing and the log line
  3. 03 The file decrypts with the passphrase from the secrets store, on a machine that is not the job's. Evidence: the decrypt exit status
  4. 04 The dump restores with pg_restore into a new, empty, isolated database, and records you know are present and match. Evidence: the restore output and the query results, dated
  5. 05 The retention is set where it lives: the host's setting, and the bucket's lifecycle rule, which on a versioned bucket also expires noncurrent versions. Evidence: the rule's text

For check 1, Supabase lists backups under Database > Backups, Railway in the attached service’s Backups tab, and Render on the database’s Recovery page. On a plan the host’s docs leave without backups, such as Render’s Free compute plan or Supabase’s free tier, check 1 cannot pass: the evidence is that line of the docs, and checks 2 to 4 carry the proof. The fuller file check before a restore, pg_restore --list and the size trend, is the restore-drill article’s first rung.

For check 4, the manual’s form is createdb -T template0 newdb and then pg_restore -d newdb db.dump, cloning from template0 so the new database starts empty. Pick records you know, such as a recent customer and their last order, and compare them rather than counting rows. Role and ownership errors on a scratch server, and the flags that avoid them, are in the restore-drill article’s “Why did the restore fail?”.

This is how we verify deliverable 4.7, Verified backups and restore, in the Production Hardening Sprint: restore a backup into an isolated environment and check representative data integrity.

The repeated, timed drill, the choice of recovery time and recovery point objectives, and the credential boundaries are in test your backups with a restore drill. A migration should never run without a fresh backup, which is where the database migration checklist comes in, and the managed database’s other settings are in how to harden managed database settings.

Where the sprint does this

In the sprint, deliverable 4.7 is to “Verify automated backups, set retention, and perform a real restore test”, checked the way the section above describes. Deliverable 4.12 goes further: we restore the application and data into a fresh environment, time the recovery, and document the procedure. Each result is recorded in the production readiness report, which accounts for all 123 IDs, keeps failures visible until resolved and explains genuine non-applicable items. Hosting, paid tools and API usage remain in your accounts, and we explain any required third-party costs before enabling them. The exact wording is at deliverable 4.7 in the published scope.

Common questions about database backups

What is the 3/2/1 rule for backing up?

The 3/2/1 rule means keeping three copies of your data, one primary and two backups, on two different media types, with one copy stored offsite; CISA gives it as the NIST 3-2-1 rule. For a single app on a managed host, the host’s backups count as one backup and an encrypted dump in another account’s bucket as the second, offsite one.

What is a SaaS backup?

A SaaS backup usually means backing up the data a company keeps in the SaaS tools it uses, such as Microsoft 365 or GitHub. For a company that runs its own SaaS product, it means backing up the app’s own database and stored files, which is what this checklist covers.

Will I lose everything if I restore from a backup?

No, but restoring over the live database loses every write made after the backup’s moment, so restore into a new database first and copy back what you need. Point-in-time recovery narrows that gap where the host sells it: a Supabase add-on on Pro, Team and Enterprise, Neon’s history window, Render’s 3 or 7 day window on paid databases, and RDS within its retention period. Whether to restore over production at all is the first-hour article’s call.

Can I use S3 for backups?

Yes. Use a bucket in a second AWS account with versioning on and a lifecycle rule that expires old files, plus noncurrent versions because the bucket is versioned, and encrypt each file before upload so the bucket holds nothing readable.

What happens if I don’t backup my data?

On a plan with no host backups, a bad migration or a deleted table leaves nothing to restore from, and the only copy is one you made yourself, if you made one. Render documents exactly this for its Free compute plan.