Restore walkthrough
Step-by-step: from the dashboard CTA to a completed restore with JSONL output.
Before you start
pg_restoreon the restore machine must match the major version of the source database. Check:pg_restore --version. If there is a mismatch, see Install the CLI.- The restore machine must have network access to the target database.
- You need a target Postgres database to restore into. For
new_databasemode, the target can be any Postgres cluster — walwarden will create a new database inside it. Forin_placemode, the target database must already exist and you must accept that it will be overwritten.
Step 1: Click "Restore from this backup"
Navigate to the database detail page for the source database. In the Backup history table, find the backup you want to restore from and click Restore from this backup.
A modal appears with a mode picker:
- New database (default) — walwarden creates a new database on the target cluster using the source database name. The target cluster must not already have a database with that name, or the restore will fail. Use this for test restores, cloning, and migrations.
- In-place — walwarden overwrites an existing database on the target. The target database must already exist. A destructive-intent warning is shown. Selecting in-place enables a checkbox: "I understand this will overwrite the target database." The Issue restore token button is disabled until you check it.
Select your mode and click Issue restore token.
Step 2: Copy the one-liner
The modal is replaced by the one-liner panel. The full command looks like:
WALWARDEN_TOKEN=<token> npx --yes walwarden-cli restore \
--manifest <sha256> \
--target '<paste-target-dsn-here>' \
--mode new_database
Click Copy to copy it to the clipboard.
The panel shows an expiration countdown. Restore tokens are valid for 1 hour. If the token expires before you run the command, issue a new one from the same backup row.
Step 3: Fill in the target DSN and run
On the restore machine, paste the command and replace <paste-target-dsn-here> with your target Postgres DSN:
WALWARDEN_TOKEN=<token> npx --yes walwarden-cli restore \
--manifest <sha256> \
--target 'postgresql://user:password@host:5432/postgres' \
--mode new_database
If you prefer not to put the password inline, omit it from the DSN and set PGPASSWORD:
export PGPASSWORD='your-password'
WALWARDEN_TOKEN=<token> npx --yes walwarden-cli restore \
--manifest <sha256> \
--target 'postgresql://user@host:5432/postgres' \
--mode new_database
Run the command.
What happens next
The CLI prints a rich progress view in a TTY, or JSONL events if stdout is not a TTY or --json is passed. A successful run produces output like:
phase: download bytes: 142MB / 142MB elapsed: 8.2s
phase: verify checksum: ok elapsed: 0.3s
phase: restore pg_restore: running elapsed: 4.1s
phase: finalize state: completed exit: 0
In JSONL mode (or if you pass --json):
{"state":"downloading","at":"2026-05-26T14:32:00.001Z","payload":{}}
{"state":"verifying","at":"2026-05-26T14:32:08.412Z","payload":{}}
{"state":"manifest_verified","at":"2026-05-26T14:32:08.723Z","payload":{"checksumSha256":"<hash>"}}
{"state":"restoring","at":"2026-05-26T14:32:08.800Z","payload":{}}
{"state":"finalizing","at":"2026-05-26T14:32:12.901Z","payload":{}}
{"state":"completed","at":"2026-05-26T14:32:13.001Z","payload":{"bytesRestored":148897024,"checksumSha256":"<hash>"}}
The CLI exits 0. The restore token is now invalidated; it cannot be reused.
Step 4: Verify in the dashboard
Return to the dashboard database detail page. The Restore history section shows the completed restore job with its full state timeline, the manifest hash, and the bytes transferred.
If the restore failed, the timeline shows the failure state and classification. See Troubleshooting.
Step 5: Verify the target database (optional but recommended)
Connect to the target database and confirm the expected tables and row counts are present:
psql 'postgresql://user:password@host:5432/restored-db-name' -c "\dt"
For a new_database restore, the database was created with the source database name. Connect to that database name on the target cluster.
A backup you have not verified by connecting to the restored database is a backup you have not fully proven. Even spot-checking one table count is better than no check.