Skip to content

Backups

backups restore recovery pg_dump point-in-time recovery PITR data protection disaster recovery

Every Pro and Team project comes with daily backups and 7 days retention. This means your data is automatically saved every day, and you can restore from any backup taken in the last week.

Free projects do not have daily backups, but you can create manual backups whenever you need them utilizing the connection string and backup tools like pg_dump.

In addition, for projects with critical data or those requiring precise recovery control, we offer point-in-time recovery as an add-on. This feature continuously backs up your data and lets you restore your database to any specific moment. It’s ideal for applications where every transaction matters and you need the ability to recover from any point in time, not just daily backups.

Something important to note is that backups don’t include your storage files. A backup will include all of your files metadata and permissions but not the files themselves. Similarly, Run services’ data (if any) is not included in our managed backups.

For details visit the pricing page

All Pro and Team projects come with daily backups enabled with a 7-day retention by default. You can view, download and restore your project’s backups by visiting the Backups section in your project’s dashboard.

To restore a backup, go to the Backups section in your project’s dashboard, pick the backup you want to restore from and click on “Restore”. Keep in mind this will wipe out all of the project’s data prior to initiating the restore.

You can restore a backup on a different project or to a database running locally by following these steps:

  1. Go to the Backups section in your project’s dashboard and download the backup you want.
  2. Uncompress it with unzip or similar tool
  3. You should see two files globals.sql and database.custom

For instance:

$ unzip a857e914-7553-4f87-8be2-47fa365a1cb8
Archive: a857e914-7553-4f87-8be2-47fa365a1cb8
inflating: globals.sql
extracting: database.custom

Global database objects (i.e. roles) are stored in the file globals.sql, you can restore those objects with psql:

$ psql postgres://postgres:postgres@localhost:5432/local -f globals.sql
SET
SET
SET
DETAIL: owner of schema auth
owner of schema storage
owner of schema pgbouncer
DETAIL: privileges for schema hdb_catalog
privileges for schema auth
owner of default privileges on new relations belonging to role nhost_auth_admin in schema auth
...

Finally, you can restore your database using pg_restore:

### We have no data initially
$ psql postgres://postgres:postgres@localhost:5432/local -c "SELECT COUNT(*) FROM auth.users"
count
-------
0
(1 row)
$ pg_restore -d postgres://postgres:postgres@localhost:5432/local database.custom --clean --if-exists
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_ident_file_mappings" does not exist
Command was: GRANT SELECT ON TABLE pg_catalog.pg_ident_file_mappings TO nhost_hasura;
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_parameter_acl" does not exist
Command was: GRANT SELECT ON TABLE pg_catalog.pg_parameter_acl TO nhost_hasura;
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_publication_namespace" does not exist
Command was: GRANT SELECT ON TABLE pg_catalog.pg_publication_namespace TO nhost_hasura;
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_stat_io" does not exist
Command was: GRANT SELECT ON TABLE pg_catalog.pg_stat_io TO nhost_hasura;
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_stat_recovery_prefetch" does not exist
Command was: GRANT SELECT ON TABLE pg_catalog.pg_stat_recovery_prefetch TO nhost_hasura;
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_stat_subscription_stats" does not exist
Command was: GRANT SELECT ON TABLE pg_catalog.pg_stat_subscription_stats TO nhost_hasura;
pg_restore: warning: errors ignored on restore: 6
### Now we do have data
$ psql postgres://postgres:postgres@localhost:5432/local -c "SELECT COUNT(*) FROM auth.users"
count
-------
247
(1 row)

Projects with Point-in-Time Recovery enabled have their data continuously backed up, not bound to a specific schedule. You can recover to almost any point in time within your retention period. We perform a daily base backup and then capture database changes every 16MB or 5 minutes (whichever occurs first). This ensures that even your most recent data is safe and can be recovered.

Point-in-Time Recovery is an add-on and not included in the base price. For details visit the pricing page. When Point-in-Time Recovery is enabled, daily backups are disabled.

You can configure Point-in-Time Recovery via the dashboard or using your nhost.toml:

  1. Go to the Backups section in your project’s dashboard.
  2. Enable “Point-in-Time Recovery”

Point-in-Time Recovery

To restore to a specific point in time:

Go to the Backups section in your project’s dashboard and click on “Start Restore”

Point-in-Time Recovery

Here you can click on the calendar icon to select the restore time:

Point-in-Time Recovery

Select the time you want to restore to and click on “Select”. Be mindfule of timezones.

Point-in-Time Recovery

Finally, acknowledge the warning and click on “Restore”

Point-in-Time Recovery

This will trigger the restore in the background, you can now proceed to the logs and filter by “Service: Backup Jobs” to see the progress.

Even though you can specify a point in time down to the second, the actual restore may include data modified after that point in time. This is because we capture changes in segments every 16MB or 5 minutes, whichever occurs first, and the restore needs to execute entire segments to ensure consistency. In some cases postgres may be able to execute the entire segment and revert some changes to get closer to the desired point in time, but this is not guaranteed.

Restoring to a Specific Point in Time on a Different Project

Section titled “Restoring to a Specific Point in Time on a Different Project”

You can restore to a specific point in time on a different project in our cloud by following these steps:

First, create a new project where we will restore the data into. The project will need to be in the same organization and region as the original project. Before starting the restore make sure the target project is running the same database version as the original project and that you have enough space available for the restore.

Go to settings -> database in both the new and the original projects and make sure the new project is running the same exact database version as the original project.

Finally, go to the new project’s Backups section, navigate to “Import Backup” and select the original project. After this the steps are the same as restoring to a specific point in time on the same project.

Point-in-Time Recovery import

Downloading a backup isn’t supported as with Point-in-Time Recovery there is no such thing as a backup that can be downloaded. However, you can restore to a specific point in time on a different project and then use pg_dump to create a backup yourself.