SafeGrd: PostgreSQL backups that are restored and checked on a schedule

From: SafeGrd via PostgreSQL Announce <announce-noreply(at)postgresql(dot)org>
To: PostgreSQL Announce <pgsql-announce(at)lists(dot)postgresql(dot)org>
Subject: SafeGrd: PostgreSQL backups that are restored and checked on a schedule
Date: 2026-10-22 09:29:42
Message-ID: 179266138279.369661.14178242300796345811@wrigleys.postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-announce

SafeGrd is a new backup service for PostgreSQL 13 and later that restores every backup on
a schedule and checks the row counts.

It takes a backup, restores it later into memory or a throwaway database, and counts what
came back, so you find out a backup is broken before you need it.

## Taking the backup

The `safegrd` daemon runs on a host next to your database and connects as a read-only
role. On PostgreSQL 14 and later that role only needs `pg_read_all_data`. On 13 you grant
each schema instead. The schema comes from `pg_dump` and the rows come over binary `COPY`,
in one transaction. After the first run, each backup uploads only what changed.

The backup is encrypted with [age](https://age-encryption.org) on your host before it
leaves, then written to an S3 bucket with Object Lock on. That can be your own bucket or
SafeGrd-hosted storage. The backup data never goes through SafeGrd's servers.

You choose how the age key is managed. With a customer-managed key, only you can decrypt
these backups. With a SafeGrd-managed key, SafeGrd keeps your key sealed and releases it
only to your enrolled hosts, so you can restore even after losing a host.

Supabase, Neon and Amazon RDS work from a connection string. Supabase backups are restored
on Supabase's own Postgres image, so the extensions in the dump load.

## Testing the backup

We call the restore test a Fire Drill. It takes the newest backup, decrypts it and checks
it in one of two ways:

- In memory. The dump is replayed without a running server, and the table, row and column
counts and the extensions are compared with what the backup recorded.
- In a sandbox. The backup is restored into a throwaway PostgreSQL database and the counts
are checked there. You can add your own SQL checks too, for example
`SELECT count(*) FROM users WHERE email IS NULL` has to return `0`.

Each drill writes a signed, dated record with the counts and the check results. Every
record points at the one before it. The
[attestation verifier](https://safegrd.dev/tools/attestation-verifier) checks the whole
chain against SafeGrd's published signing key in your browser, with nothing to install.

## Trying it

curl -fsSL https://safegrd.dev/install.sh | sh
safegrd login
safegrd enroll

The [CLI source](https://github.com/safegrd/cli) is on GitHub under the Business Source
License 1.1.

The free plan covers one database. It is backed up daily to SafeGrd-hosted storage, or
hourly to your own bucket, and drilled in memory once a week. Paid plans start at $15 a
month and add hourly backups, sandbox drills and more databases.

Docs: [safegrd.dev/docs](https://safegrd.dev/docs)

Browse pgsql-announce by date

  From Date Subject
Next Message IVM Development Group via PostgreSQL Announce 2026-10-26 13:14:51 pg_ivm 1.17 released
Previous Message DevCrafterAI LLC. via PostgreSQL Announce 2026-10-22 09:29:32 pgrecon: open-source Oracle to PostgreSQL migration assessment and schema conversion