Skip to main content

Backups

What is copied, where it goes, how long it is kept, and what you have to do to get one back.

Production environments are backed up without you doing anything. Two things are copied: the database, and the files your application has written — uploads, generated exports, anything under the directories that survive a release.

Your code is not backed up, because it is in git and in a build artifact already. Restoring a repository from us would be restoring it from a worse copy.

#Where a copy goes

Copy Where
Near object storage (Cloudflare R2) on the same continent as your machines
Cold a different provider, in the EU: Scaleway, in Paris
On the machine the database only, for the last two days

Two offsite copies, on different providers. A backup that shares a fate with the thing it protects is not a backup — and one that shares a provider with it is only slightly better.

The near copy follows your machines. The cold copy recently moved from Hetzner in Helsinki to Scaleway in Paris; until the new one holds enough history, both are written, so nothing already kept is lost in the move.

The copy on the machine is the one that survives a dropped table or a bad deploy, which are the restores people actually ask for; it is the database only, because a copy of your files on the same disk as your files protects against nothing. It keeps everything from the last 48 hours and never fewer than the three most recent, and a restore reads from it first because nothing has to leave the machine.

#Keeping a copy of your own

Under Backups on your team, you can point backups at storage you control as well. Two steps, because the credentials belong to your team rather than to one destination:

  1. Add the storage under Integrations, once — S3-compatible object storage, an SFTP host or an rclone remote. On S3, give it the bucket backups should go in, and a destination appears on its own.
  2. Otherwise add a destination under Backups and pick the integration. It asks for a name and nothing else: where it writes and what it signs with come from the integration, so rotating a key there fixes every backup that uses it.

This is additive. Connecting your own storage asks for a copy inside your boundary; it does not stop us keeping ours. It is also how non-production environments get backed up offsite, since we do not do that for you.

#When they run

Once a day, between 05:00 and 07:00 local to the continent your machines are on — so a backup is not running while your visitors are.

The database can be copied every four hours instead. That is an add-on on production, available on either plan and bought under Commercial terms, and it is included on the Dedicated shape. Files stay once a day whatever the database does: uploads change slowly, and the data somebody actually loses in an afternoon is in the database. The extra dumps are kept for a week; beyond that the daily series is what reaches back.

If a backup is missed — the machine was rebuilding, something was down — it runs as soon as it is noticed rather than waiting for tomorrow. A backup that keeps failing is worth a notification: nothing else notices until somebody needs to restore.

#What is kept

Production Staging Development
Daily 7 3 1

Deliberately shallow. The restores people ask for are from the last few days, and a snapshot from a year ago restored today is a different site rather than an older one.

The same on either plan. How far back a series reaches is not decided by whether a project is shared or dedicated — it is bought for production, and changed whenever you like under Commercial terms on the project's configuration page. Thirty days instead of a week keeps a snapshot for each of the last thirty days, with a weekly and a monthly alongside, and it is the one that catches a problem nobody noticed at the time — the mistake you find on your next invoice rather than the same afternoon. The database can also be dumped every four hours rather than nightly, bought the same way.

The staging and development counts apply where those environments have a backup at all — on your own storage, or the database copy on their machine; see below.

A backup you take by hand is kept for 30 days, regardless of the counts above. Somebody taking one is usually about to do something risky, and what it protects against tends to surface days later — after seven dailies would have rolled it off.

#Non-production environments

We do not back up staging or development offsite. What we pay to store is the data you cannot reproduce, and a staging environment is a deploy away from existing again.

They keep the database copy on their own machine, which is what saves a botched migration. If you want them kept properly, connect your own storage.

#Restoring

Backups → Restore a snapshot on the environment. It replaces what is there now — anything written since the snapshot is lost — so it asks you to confirm.

Production can only be restored from its own history. Putting staging's database into production is not a restore; it is replacing the live site with a copy of somewhere your developers have been working.

#The encryption key

Every repository is encrypted, and each one has a key of its own. A repository is one environment at one destination, so an environment writing to three places has three repositories with three unrelated keys. That is deliberate: a key decrypts the whole repository it belongs to, so sharing one across environments would mean a staging machine holding something that could read production.

The key is generated when the repository is first created, 256 bits from the system's random source, and stored encrypted. It is handed to a machine only for the job that needs it and never written to a task record.

Losing it makes that repository unreadable — by you, by us, by anyone. Restic has no way to change a repository's password without rewriting the repository, so it is the same key for the life of the backups.

#Taking it with you

Where the destination is your own storage, the key is yours to have: the team's Backups page lists every repository on it, with Show the key beside each. With your own credentials and the key you can restore anywhere, with no involvement from us — restic -r <repository> restore. It takes an Admin or the Owner rather than anybody who can restore, because one string decrypts every snapshot in that repository, including ones taken before you joined the team, and cannot be changed afterwards — somebody who leaves the team keeps it.

On the platform's own destinations the key is not offered, and it would not help: those buckets hold every customer's backups behind credentials that are ours, so the key would unlock something you cannot reach. What works there is an export — see below — or bringing your own destination, which is the recommended arrangement for exactly this reason.

#Taking a copy out

Backups → Prepare a download turns one snapshot into a plain copy — a database dump or the files — and gives you a URL to it. That is the route out that always works, on any destination: it is decrypted on the machine, so you need no key and no credentials of ours.

What comes out is unencrypted and the URL needs no further authentication, so it asks you to confirm before it is made. The link expires shortly after it is ready; prepare it again for a fresh one.

#When a subscription ends

The machines are destroyed a day after the end of the period you paid for. The backups are kept for thirty days after the subscription ends, so the site can be brought back, and then deleted from our storage — the data itself, not only the record of it.

A copy in your own storage is not ours to delete and stays where it is, with its key still yours: that is the one copy that outlives the subscription for as long as you want it to.

#Copying data between environments

Backups → Copy from another environment. This is how you get realistic data into staging. It is not read from a backup: the receiving machine asks the source for a fresh database dump and copies its files across directly, so what arrives is what the source holds right now. It replaces rather than merges — the database is rebuilt and the file directories mirrored, so nothing that was there before survives beside it. A deploy follows.

The deploy is not optional and not cosmetic. The database that arrives belongs to whatever code the source was running, and the environment receiving it is running its own — so the update hooks and configuration import have to run for the two to agree. Without that you have a database and a codebase that disagree, which shows up as a fatal on the first page anyone opens.

Nothing is scrubbed unless you say so. See below.

Not available into production, for the same reason a cross-environment restore is not.

#Resetting a database

Backups → Reset database empties the environment's database and starts it again on the version vallic.yaml declares, with a backup taken first and the newest backup restored after. It exists for one job — moving to a database version that cannot read the old files — and Service upgrade is where to start if that is what you are doing. Only an Admin or the Owner can do it, and only by typing the environment's name.

#Sanitising what arrives

We do not scrub anything on our own. We cannot: we do not know which of your tables hold people. Guessing would produce a result nobody could rely on — scrubbed enough to look handled, not enough to be.

So you declare it, in .vallic/commands/sanitization.yml:

commands:
  - 'drush sql:sanitize --yes'
  - 'drush sql:query "UPDATE orders SET customer_email = CONCAT(id, ''@example.test'')"'
  - 'drush sql:query "TRUNCATE payment_tokens"'

They run in your application container, in order, immediately after the database arrives — from a copy or from a restore into that environment — and before anyone can reach the environment. The first one to fail stops the rest and fails the task — a half-scrubbed environment holding real data while looking handled is worse than one that visibly did not finish.

If the file is not there, nothing runs. Production data lands in staging exactly as it was, and every developer with access to that environment can read it. That is worth deciding deliberately rather than discovering.

The file is read from the environment receiving the data, on the branch it is running — so staging's copy governs what happens to staging.

Never on production. A restore into production is production being put back from its own history, and that data belongs there — so the file is not read and nothing runs, whatever it declares. Nothing can be copied into production from another environment either, so there is no case where production is scrubbed.

Other files can live in .vallic/commands/ later; sanitisation is the first.

Next

Logs covers the other thing that leaves the machine, and Shell access covers importing a database dump by hand.