Point-in-time recovery
Restore to any moment covered by a verified base backup and a gap-free WAL chain. How to run one, how to pick a target, and what an in-place restore destroys.
Point-in-time recovery restores your database to a specific moment: the second before a bad migration, the minute before a deletion.
You run it from the Backups tab, and you choose between two operations that are not interchangeable. One creates a new service. The other overwrites this one.
Run a restore
- Open the service and select the Backups tab.
- Find the Restore panel. It is headed "Point-in-time recovery from a backup repository."
- Choose a repository. Either of the two holds your chain.
- Choose a point in time, between the earliest and latest recoverable points shown.
- Under What should happen, choose one:
- Restore into a new service, then give it a Name for the new service. Lowercase letters, digits and hyphens; it appears in the new endpoint hostname.
- Restore in place, which overwrites this service.
- Confirm.
A service runs one operation at a time. If one is already running, wait for it to finish.
Restore into a new service
The default, and the one to use when you are not certain. The restore is provisioned as a separate service, so your existing service keeps running and you can compare the two before switching anything.
This is also how you answer "what did this table look like on Tuesday" without touching production.
Restore in place
Restores over the existing service. This destroys the current contents of that service.
It exists because sometimes the endpoint has to stay the same, and reconfiguring every client is a worse risk than the restore itself. The interface treats it as destructive: you tick a box saying you understand that everything written after the target will be discarded, you confirm in a dialog headed Restore in place., and the action is written to your audit log.
What has to be true for a target to be reachable
A point in time is recoverable when there is a verified base backup before it and an unbroken chain of write-ahead log segments from that backup up to the target.
Both halves matter. A recent WAL upload proves nothing on its own: if a segment in the middle of the chain is missing, everything after it is unreachable. That is why recovery point exposure is computed from the chain rather than from the last upload timestamp, and why a gap raises an alert rather than a graph.
Picking a target
Two habits worth having:
- Aim just before the event, not at it. If a bad migration started at 14:32:10, target 14:32:00 rather than 14:32:09.
- Restore into a new service first, look, and only then decide. A restore is much cheaper than a wrong restore.
What you will see
The panel shows the earliest and latest recoverable points per repository, and an explicit unknown when the evaluation is stale.
A restore runs as a job and the Activity tab records it. A restore into a new service produces a new PostgreSQL instance with its own endpoint and its own credentials, so your connection strings do not carry over. It gets its own backup schedule immediately, and a restore verification within the mandatory window after creation.
After any restore, run ANALYZE, and check your application against the result before you move
traffic.
Troubleshooting
"There is no point in time to restore to yet." The service has no verified base backup. The first one follows within 48 hours of the first successful backup.
"Restores are paused while the account is unpaid." The organisation's billing state does not currently allow the operation. See payment failures.
resource.operation_in_progress. The service already has a job running. Wait for it.
The target you want is greyed out. It is outside the recoverable range for that repository. Try the other repository, and check your retention period. See retention.
The new service is slow. Run ANALYZE. A restored database has no statistics until you do.