Skip to main content

Restoring your app

When something goes wrong in production, you put your app back the way it was yourself, from the console: go back to just before a deploy, run a version of your app that worked, or rewind only the database. No ticket, no terminal, no waiting on someone else.

And when you want to be sure first, run the restore as a restore preview: a private copy of your app next to production, with the restored data, while production keeps running untouched.

Restores draw on the restore points described in Backups & recovery. Project owners and admins can restore; every member can see the restore points.

Start from what went wrong​

Open your app's Backups section and click Restore…. The console asks what went wrong and gives you a starting point for each answer:

What went wrongChooseWhat changes
A deploy broke somethingGo back to before a deployThe app, the database, and the files all return to the moment just before that deploy.
Only the app is brokenRun an older versionOnly the app. It runs on today's data, so no data is lost.
Data was changed by mistakeRewind the databaseOnly the database. The app and the files stay as they are.

Each starting point fills in the three parts of a restore: the app (which version runs), the database, and the files in your persistent volumes. You can adjust any part before anything happens. For any other combination, Custom restore lets you choose part by part.

Go back to before a deploy​

Right before each new version of production starts, AppHaven takes a restore point, listed as Before deploy. That makes the most common recovery a single choice: pick the deploy that broke something, and everything returns to the moment just before it. The app goes back to the version that ran before that deploy, and the database and files go back to how they were while that version was still running.

The most recent deploys are listed right away. Older ones are grouped per day, and you can search them by commit or message.

When you restore production this way, database records and files written after that moment are deleted. If you need to keep some of them, restore to a restore preview first and copy back only what you need.

Run an older version​

Pick a production version that worked, and AppHaven runs exactly the build that ran then. It is not rebuilt from the commit: the same image goes live, so what you get is what already worked once. Your database and files stay as they are, so no data is lost.

Every version that ran in production within your backup retention window is available; see App versions for how they are kept.

One question is worth answering first: does the older version still work with today's database? If a deploy since then changed the database schema, for example by adding a required column or renaming one, the older code may not match today's data. The console offers a question you can copy into your coding agent, "are there database schema changes between f41d9e0 and a0c55e1?", and with the AppHaven plugin the agent answers it from your repository's migrations. When you are unsure, run the older version as a restore preview first.

Deploying an older version to production works like any other deploy: no data is deleted and no restore steps run. Your production branch itself does not change, so the next push to it deploys as usual. Revert the bad commit on the branch, so that push does not bring the problem back.

Rewind the database​

Choose a moment on the timeline, or type a date and time. The timeline spans your whole retention window and marks each deploy, so "just before Tuesday's deploy" is easy to find. The console lists the restore points around the moment you chose, and the database goes back to the one you pick.

Only the database changes; the app and the files stay as they are. When you restore production, database records written after the restore point are deleted.

This option needs a managed database in your app.

Custom restore​

Start from a restore point, then choose for each part what to bring back: restore it from that point, or keep it as it is now. Pick the app version the same way: a kept production version, or the one running now.

Where the restore runs​

Every restore has one target, and you choose it before you review:

  • Restore preview: a new, private deployment next to production, with a copy of the restored data. Production keeps running and is not touched.
  • Replace production: production itself is put back.

Restore previews​

A restore preview is a deployment of its own, with its own copy of the data you restore, at its own address. Use one to:

  • check that a restore point holds what you expect, before you replace production;
  • try an older version of the app against today's data;
  • find database records or files that were changed or deleted by mistake, and copy back only those, while production keeps running.

What to know about a restore preview:

  • It is always private. Only members of your project can open it, after signing in, whatever your app's access mode.
  • It is a full copy. Nothing you do in the preview reaches production, and nothing production does afterwards reaches the preview. Making the copy takes longer the more data there is; the console shows its progress.
  • It shows up in your deployments, named after the day it was made, for example Restore preview 27 Sep.
  • It does not take a preview slot. It does not count towards your app's maximum number of previews. It does run at your app's size, so it counts towards your project quotas like any running deployment.
  • It runs until you delete it. It is not stopped automatically and it is not backed up. Delete it when you are done to free its resources.
  • It stays a preview. To bring production to the same state, restore production from the same restore point.

Keep a restore preview from acting on real customers​

A restore preview runs with your app's Variables and Secrets, against a copy of your production data. Whatever was waiting in that data runs again: scheduled jobs, queued emails, pending payments and webhooks, with the same keys production uses. A cleanup job can remove files from storage that production shares with it, such as an S3 bucket, because the preview's older database does not know about them. When the preview copies data as it is now, all of this happens at the same time as production.

Your app decides what a restore preview may do. It can tell it is running in one from the APPHAVEN_ENVIRONMENT variable, which is restore there. Let only production (prod) send email, take payments, call webhooks, run scheduled jobs, and clean up shared storage. The console reminds you of this on the review page whenever you restore to a preview.

Replacing production​

Review first. Before anything happens, the review page lists every part with exactly what will happen to it: Restore to 29 Sep 14:19:58, Keep, or Deploy f41d9e0, along with the target. This is where you change a part if it is not what you want.

Confirm data loss explicitly. When the restore deletes data in production, the review page says so first, with the period that is deleted for each part. You confirm by typing the app's name before Restore production becomes available.

Production is offline while it restores. The Backups page shows each step as it happens: saving, stopping, restoring the database, restoring the files, starting, checking. Putting the data back takes about the same time whether your database holds megabytes or gigabytes; most of the wait is your app stopping and starting. If someone pushes to the production branch during the restore, the push waits, and the latest one deploys once the restore is done.

Nothing is lost for good. Right before production is replaced, AppHaven takes one more restore point, listed as Before restore. If the restore was not what you needed, you can return to that point the same way. The database change stream starts afresh at the restore, so point-in-time recovery starts over from there. Earlier restore points stay available.

When a restore does not finish. A restore that cannot start (for example, because the restore point has just expired) changes nothing: production keeps running as it was, and the console says why. If the data is restored but your app does not come back healthy, the console tells you, and the Before restore point is your way back.

In rare cases a restore stops partway through after production was already stopped. Production then stays stopped to keep your data safe, and the console asks you to contact support. Until support has finished the restore, you cannot deploy, stop or start production, and it is not billed. Billing resumes by itself once production runs again.

Production can be replaced up to five times within your retention window. Each time, the data it replaced is kept for the rest of that window. When five are held, the console shows the date the next restore becomes available.

What a restore can bring back​

PartGoes back to
AppAny production version that ran within your retention window, exactly as it was built
DatabaseAny restore point within your retention window
Files (persistent volumes)Any restore point within your retention window

Prebuilt images: name the exact version​

For services AppHaven builds from your repository, the app version is the exact image that ran. For a service that uses a prebuilt image:, the version is the image reference in your manifest, and a restore fetches that reference again. Write a specific tag, such as ghcr.io/example/app:1.4.2, or a digest (ghcr.io/example/app@sha256:…), so that a restore runs exactly that image later. A moving tag such as latest brings whatever it points to at the moment of the restore, also when you only rewind the database.

Where to go next​