Skip to content
ForgeVPS

Work with your VPS

Practice a restore before you need one.

Create, download, and restore a PostgreSQL backup in ForgeVPS. Use a disposable database to verify recovery before restoring real application data.

A PostgreSQL backup is useful when you know you can restore it. ForgeVPS can take, download, and restore database backups from the Databases pane. This walkthrough uses a disposable database so you can see exactly what comes back before touching application data.

You need a connected machine with PostgreSQL and ForgeVPS's database backup tooling set up. If Back up now reports that backups are not ready, complete the machine setup steps from its Dashboard first.

1. Create a practice database

Open your machine's Databases pane, choose New database, and create backup_practice. If that name already exists, choose another unused name. Do not run the practice steps against a database your app uses.

Open the new database's SQL editor and run:

CREATE TABLE public.backup_notes (
  id integer PRIMARY KEY,
  note text NOT NULL
);
INSERT INTO public.backup_notes (id, note) VALUES
  (1, 'Saved before the backup'),
  (2, 'This row should come back');
SELECT id, note FROM public.backup_notes ORDER BY id;

You should see two rows. These give you something concrete to verify after the restore.

2. Take and download the backup

Open Backups for backup_practice and choose Back up now. Wait for the new entry, record its filename and time, and download a copy. Make sure you can identify this exact backup later.

ForgeVPS stores compressed SQL dumps as .sql.gz files under ~/.forge/backups/<database>/ on the VPS. A copy on the same server will not protect you if the server or its disk is lost. Keep another copy somewhere you control, with access appropriate for the data it contains.

The Keep setting counts backup files, including manual backups. It is not a guaranteed number of days. Download an older recovery copy before creating more backups if retention might remove it.

3. Make a visible change

In the practice database's SQL editor, change one row and delete the other:

UPDATE public.backup_notes
SET note = 'Changed after the backup'
WHERE id = 1;
DELETE FROM public.backup_notes WHERE id = 2;
SELECT id, note FROM public.backup_notes ORDER BY id;

The result should now contain one row with the changed text. The backup still contains the original two rows.

4. Restore the earlier copy

Return to Backups, find the backup you recorded, and choose its restore action. Confirm that the dialog names your practice database. Type that database name and choose Restore backup.

Restoring replaces the objects contained in the dump with their earlier versions. Changes made to those objects after the backup are lost. This is why the exercise uses a disposable database.

Wait for the restore result. If it reports an error, read that error before retrying: the current restore operation can apply some SQL before failing. Do not assume an error leaves the database unchanged.

5. Check what was restored

Run the query again:

SELECT id, note FROM public.backup_notes ORDER BY id;

Expect row 1 to say Saved before the backup and row 2 to say This row should come back. Refresh the table view if it still shows the earlier result. You have now checked the data itself, rather than relying only on a successful restore message.

For a real app, also verify representative records, relationships, login, and the actions that read or write this database. A dump restoring without errors does not prove the application is compatible with it.

Before restoring a real application database

  1. Identify the recovery point. Choose a backup from before the unwanted change, and download it so retention cannot remove your only copy.
  2. Preserve the current state. Take and download a separate backup before overwriting data you may still need.
  3. Test in a separate database when possible. The ForgeVPS restore button targets the database whose Backups dialog is open. Restoring a download to a different database requires a separate SQL restore workflow.
  4. Pause writes before an in-place restore. Account for the web app, background workers, scheduled jobs, and external integrations. Stopping only the website may leave other writers active.
  5. Verify before resuming traffic. Check the restore result and application behavior, then re-enable writes once the recovered state is acceptable.

A compressed plain SQL dump is restored with psql after decompression; it is not a custom-format archive for pg_restore. Use an empty target database and the intended database role when testing a separate restore. PostgreSQL's SQL dump and restore documentation explains this process and error handling.

Know what this backup does not contain

A database dump is not a full VPS snapshot. It does not back up your application files, uploaded images, environment settings, or every database role on the server. Keep recovery copies of those separately.

The dump includes cleanup instructions for the objects it contains; it is not a complete reset of everything that might now exist in the database. Objects created after the backup may remain or interfere with restoration. For a clean recovery test, restore into a separate empty database.

These backups recover the state captured by each dump, not an arbitrary second between backups. Choose a backup frequency and retention policy based on how much work you can afford to lose, and repeat the restore exercise after important changes.

If your problem began with an application release, also read how to fix a failed VPS deployment. A code rollback and a database restore solve different problems, and they need to leave compatible versions of your app and data.