Backups and restore
Making a backup
Section titled “Making a backup”The instance’s Backups tab makes hosted or local backups directly on the website. It offers a local backup only where the instance’s host has room for one of its disk, and shows what a backup costs per GiB to create, to restore and for storage. A backup is accepted for at most the charge of a backup as large as the disk, and needs that much available plus $1.
ghost backup create <INSTANCE_UUID> --destination local --waitghost backup create <INSTANCE_UUID> --destination hosted --waitbackup create prints what it costs before it signs the charge: a backup’s
price per GiB and the most it can cost for the instance’s disk, with the
storage and restore prices it will keep.
| Destination | Where it is kept | Restores to |
|---|---|---|
local |
On a drive of the instance’s host | Its original host only |
hosted |
Independent off-host storage: the platform’s object storage nearest to the instance’s host by distance, currently in Frankfurt (Germany), Los Angeles (USA), or Singapore | Any architecture-compatible offering |
What a backup costs, and when it is charged, is under Backups on the pricing page.
Hosted backups
Section titled “Hosted backups”- A hosted backup stays where it is kept. Its restores and the instances created from it read it from there, and when that storage is unavailable the backup fails rather than going elsewhere.
- The host encrypts it before it leaves. The website creates hosted backups itself, encrypted to the account’s current recovery public key.
- It uploads at up to its host’s backup upload limit, which all hosted backups of the host share: 32 Mbit/s, about 4 MB/s, unless the provider set another.
How a backup is made
Section titled “How a backup is made”- The source hypervisor compresses and encrypts each local or hosted backup while streaming it from the instance, and stores all-zero regions of the disk without data.
- Backups and restores are streams of bounded size rather than full temporary disk copies. Running instances use a point-in-time pull backup; stopped instances use a read-only disk export.
- A backup keeps the firmware, BIOS or UEFI, that its instance booted with.
Backing up a running instance
Section titled “Backing up a running instance”A running instance can always be backed up, and keeps running meanwhile.
- Its host keeps 16 GiB for the blocks the instance overwrites during the backup.
- An instance that overwrites more than that before the backup has read its
disk is paused until it has, and resumed then: nothing it wrote is lost, but
it does not answer meanwhile, for as long as the rest of the backup takes.
The job’s result says whether that happened (
upload_parts.guest_paused). - An instance that writes a lot is best backed up while it is stopped, or when it writes least.
- A stopped instance’s backup needs no room for writes, so its hosted backup keeps nothing on the host. The instance cannot be started until its backup has finished.
Waiting for a turn
Section titled “Waiting for a turn”A host makes two backups or restores at a time, of running instances or
stopped ones. A further one is accepted and waits for its turn, and its job
says so and how many are ahead of it, for example
waiting for a backup slot on its host, which works on 2 backups or restores at a time; 1 ahead.
On the website, its progress line says so.
- The backups of running instances also take turns at the host’s two 16 GiB scratches, so a third such backup can wait for one.
- A host whose local backups are kept on hard disks makes one local backup
or restore of them at a time, since two at once would each run far slower
than one after the other. One that waits says
waiting for the host's backup disk, which works on one backup or restore at a time; 1 ahead. Hosted backups, and local backups kept on SSD or NVMe, are not held up by it. - An instance takes no other job while its backup waits or runs.
| State | Meaning |
|---|---|
queued |
Waiting for its turn |
staging |
The host has begun it |
uploading |
A hosted backup uploads and finishes |
available |
Done |
When a local backup does not fit
Section titled “When a local backup does not fit”A local backup reserves room for its artifact, about the root disk, in the
host’s backup storage. Each offering’s backup_limits says which backups fit
on every one of its hosts while nothing else holds that storage:
local_running, local_stopped, and hosted_running. When the
host cannot take a local backup, Gigahost does not accept it. The message
names the sizes and what would fit, and says whether a hosted backup would fit:
| Code | Meaning | What to do |
|---|---|---|
local_backups_unavailable |
The host has no backup storage and keeps no local backup of any size | You can use --destination hosted |
backup_too_large_for_host |
No backup storage of the host could hold a local backup’s artifact even when empty | You can use --destination hosted |
backup_storage_busy |
Other local backups fill that storage | When some are still running, retry once they finish. Stored local backups keep their room until they are deleted, so otherwise you can delete a local backup of yours on that host, or use --destination hosted |
Scheduled backups
Section titled “Scheduled backups”An instance’s backup schedule makes its backups on time and deletes the old ones it made. It has up to 4 rules, each a destination (local or hosted), a frequency (daily, weekly on a weekday, or monthly on a day from 1 to 28, which every month has), a time of day in UTC, and how many of that rule’s backups to keep. “Daily local, keep 3; weekly hosted, keep 2” is two rules.
The Backup schedule section of the instance’s Backups tab lists its rules in a table, each with its storage, next run and how its last run went, and has a row for each rule the schedule can have: a frequency (Off for no rule, which switches the row’s other fields off), where its backups are stored, the time in UTC, the weekday (for a weekly rule only) or day of the month (for a monthly rule only), and how many to keep. Choosing a frequency fills in the usual values: 03:00 UTC, Sunday, day 1, and a keep of 3 for daily, weekly and monthly rules alike. Save schedule replaces the schedule with the rows: a row of an existing rule changes that rule (its storage can change only while it has no backups beyond failed or deleted ones), an empty row set to a frequency adds a rule, and all of them Off clears the schedule. When a lower keep would delete backups, Save schedule asks first and says how many of each rule’s oldest go. After a save the rows are the saved rules, so you can change them again without reloading the page. A row offers Local only where the host has room for a local backup of the running instance. In the backup lists, a scheduled backup names its rule beside where it is kept, such as Local · Daily schedule.
ghost backup schedule set <INSTANCE> --rule daily:local:3 --rule weekly:hosted:2 --at 03:00 --weekday sunghost backup schedule show <INSTANCE>ghost backup schedule clear <INSTANCE>A rule is FREQUENCY:DESTINATION:KEEP. --at, --weekday and --day give
the time, weekday and day of the month of each rule that names none of its
own; a rule names its own after it, as @HH:MM and /DAY, so two rules can
differ: --rule daily:local:3@01:30 --rule monthly:hosted:6@04:00/1.
set reads the schedule first and finds, for each rule you give, the
existing rule it changes in place, each existing rule at most once: one
equal to it in every field; else the only one left of its frequency and
destination at its time and day, whose keep changes; else the only one left
of its frequency and destination. Any other rule you give is new, so
running the same set again changes nothing. When a lower keep would
delete backups, set says how many of which rule’s oldest go and changes
nothing unless you add --yes. show lists each rule’s ID, and says when a
rule is deleting backups beyond its keep.
- When it runs. Each backup starts within the hour after its rule’s time, at an offset that is the same for every rule of the instance and differs between instances, so a host’s backups do not all start at once; the host then runs it as it runs any backup, after the backups ahead of it. A run missed while the host or the platform was down runs once when it can, never once per missed time: a backup still waiting for its host counts as the run of the times the host misses. Two rules due together run one after the other. The instance is backed up whether it runs or is stopped.
- What it keeps. Each scheduled backup records its rule. Only once a new one has completed are that rule’s oldest backups beyond its keep deleted, with the usual deletion. A failed run deletes nothing, so a rule never falls below what it keeps through failures. Backups you make by hand are never deleted by the schedule.
- Changing it. A rule you change keeps its backups: its frequency, time,
day and keep can change, and its next run follows its new time. A lower
keep deletes its oldest backups beyond the new keep within a minute or
so, as a completed run would, and the website and ghost ask first, naming
how many; the answer gives each rule’s completed backups
(
completed_count) beside its keep. Its destination can change only while the rule has no backups other than failed or deleted ones, since its backups are kept there; otherwise the change is refused, and to back up elsewhere you remove the rule and add another. Changing a rule is your consent again to its runs’ charges. - Removing a rule. A rule you remove (set to Off, or left out) keeps its backups, and the schedule never deletes them: the answer, the message after Save schedule and the section on the website say how many each removed rule left, which you can delete by hand when you no longer need them.
- Charges. Setting a schedule is your consent to each run’s charge: every run is charged as a backup made by hand, at the prices in force when it runs, and a price change reaches the runs with the usual notice. A run your balance cannot pay is skipped, and you get a notification (once, until a run makes its backup again). A run that a limit or the instance’s state refuses is skipped too, and the schedule shows why. The monthly spending counts the schedule’s backups once they exist, at their storage price as any backup; the runs to come and their creation charges are not projected.
- Keys. Hosted scheduled backups are encrypted to the account’s recovery public key, as the website’s are, so a schedule needs no account key to run; restoring a hosted one needs it, as ever.
- Limits. The keeps, with one more for each rule, must fit the account’s backups-per-instance limit (Resource limits) together: a rule holds one more backup than it keeps from when its next run starts until its oldest beyond the keep is deleted, and a backup is accepted only while the instance holds fewer than the limit. A schedule that keeps more is refused and names the limit. A schedule’s runs and its deletions are not counted toward the daily job limit, so many scheduled instances leave your own jobs room; a run is still skipped while your own jobs have reached it.
- Ends. Deleting the instance ends its schedule; its scheduled backups stay, as any backup of a deleted instance does.
Cancelling a backup
Section titled “Cancelling a backup”Cancel beside the backup on the instance’s Backups tab and the Backups page, or Cancel backup on the backup’s own page, withdraws a backup that still waits for its turn.
ghost backup cancel <BACKUP_UUID>- A backup that still waits is cancelled at once and costs nothing, and the instance takes other jobs again. The backup then counts as deleted, and its job, which the command names, as cancelled.
- A backup the host has begun gets
backup_started. It runs to its end, and you can delete it then. - Only the platform’s operator can cancel a backup the host has begun: if one
holds your instance too long, open a support ticket. Such
a backup reads
failed(on the website, it shows as failed), its job is cancelled withcancelled_by_operator, and nothing is charged for it.
Listing and inspecting backups
Section titled “Listing and inspecting backups”ghost backup listghost backup list <INSTANCE_UUID>ghost backup list --allghost backup list --state failed --state in_progressghost backup list --hosted --sort costghost backup list web-1 --local --sort size --ascghost backup list --tag env:prodghost backup get <BACKUP_UUID>The website’s Backups page lists your backups, the first column being the
Instance, and each backup has its own page (/backups/BACKUP_ID).
backup listleaves deleted backups out unless--allis given (include_deleted=truein the API).- The list can be narrowed to one instance, to some states and to where the
backups are kept, and sorted by age, size or what their storage costs a
month:
--statekeeps the backups in a state:queued,in_progress(being made, restored or deleted),available,failed,lostordeleted. It can be given more than once. A state given takes the place of--all, so--state deletedlists the deleted ones alone.--hostedkeeps the backups Gigahost hosts,--localthose on their instance’s host.--tagkeeps the backups of the instances that carry a tag, deleted instances too; given more than once, those of instances that carry every one of them.--sortorders them byage(the default),sizeorcost, the newest, largest or costliest first;--ascturns the order round. Backups of the same size or cost follow each other in the same direction by their creation time. Backups without a size yet, which are still being made or failed before they were, come last either way.- On the website, the Backups page has the same filters above the
list, and its Created, Size and Storage headers sort it; the
page’s address keeps the filters and the sort, so a link or the back
button brings the same list back. Its instance filter offers every
instance you have backups of, deleted instances too, and its tag filter
your tags. The API takes them as
instance_id,state(repeated),destination(hostedorlocal),tag(repeated),sortandorder(ascordesc) onGET /v1/backups.
- It prints one line per backup: its ID, its instance’s name,
status, destination (
hostedorlocal), image, size, what its storage costs a month (per_month; none for a deleted or lost backup, which costs nothing more), and creation time, and its purpose when it is not a regular backup. When one of them is a container instance’s backup, aKINDcolumn tells the two apart, and its image is the container image it ran. backup get, a deleted backup included, and--jsonshow all of it: its disk size, the smallest root it restores to, the firmware and image its instance had when it was taken, the hostname the instance had then (hostname) and its name, hostname and state now, its prices, the fingerprint of the key a hosted backup is encrypted for, and for a local backup the host and location that store it. In JSON,storage_cost_microusd_per_monthis what its storage costs a month: its size in whole MiB times its storage rate per GiB, over 1024, rounded up. A deleted or lost backup is no longer charged; the field keeps what keeping it cost, and--sort costorders it by that.- In JSON a hosted backup’s destination reads
gigahost_s3. - A backup knows its instance, so
backup cancel,backup restoreandbackup deletetake the backup’s UUID alone. For the latter two, the older form with the instance’s UUID first still works.
Final recovery backups
Section titled “Final recovery backups”The Backups page highlights final recovery backups left after balance exhaustion; see If your balance runs low.
Restoring over the instance
Section titled “Restoring over the instance”Restoring a local backup over its instance is direct. Restoring a hosted backup opens an approval page.
ghost backup restore <BACKUP_UUID> --yes --waitbackup restore prints the restore charge before it signs it.
- Only an
availablebackup can be restored or give a new instance:ghostdeclines any other before it signs anything, withbackup_not_available, and says to retry once a backup still being made, or restored, is done. - A restore also gives the instance the backup’s image in
ghost instance get. - While a restore writes the instance’s disk, the instance reads
provisioning, as during a reinstall. - A restore writes only the data the backup holds, so it takes about as long as that data, not as the disk is large.
- Restores retain the backed-up users and SSH keys and install no fresh
ones. A restore over the original instance keeps its hostname, network
configuration, SSH host keys, and
/etc/machine-id.
Firmware
Section titled “Firmware”A backup restores over its original instance only while that instance boots with the same firmware, BIOS or UEFI, as when the backup was taken. After a reinstall with an image that boots with the other firmware, create a new instance from the backup instead.
A container’s image
Section titled “A container’s image”A container instance’s backup restores over its instance only while the instance runs the image the backup was taken of, at the same version. After a redeploy onto another image or version, the backup’s disk holds the old image, which would start with the new image’s settings, so creating a new instance from the backup is the way to get it back. Backups taken since the redeploy restore over the instance as usual.
Disk size
Section titled “Disk size”- Restore replaces the current root volume only after the size checks pass. The new root disk needs to be at least as large as the source.
- The restored disk keeps its partitions and filesystem at their backed-up size, and the platform does not change them.
- Every catalog image runs cloud-init’s
growpartandresizefson every boot, so a system restored from one grows into a larger disk on its next boot while cloud-init is still installed and enabled. - On other systems, growing the partition and filesystem is up to you, for example
with
growpart /dev/vda 1and thenresize2fsorxfs_growfs.
Approving a hosted backup’s restore
Section titled “Approving a hosted backup’s restore”Only your account key can decrypt a hosted backup. A hosted backup’s restore
from the website, over its instance or into a new instance, opens an approval
page (/approvals/REQUEST_ID). The website makes local and hosted backups,
restores local ones and creates instances from them itself.
The approval page, ghost and the desktop app approve the same request in the same way, so whichever you use, and however often you start over, it is one restore and one charge.
The page shows three ways to approve side by side: in the browser with your
account key, in Gigahost desktop, and with the ghost account approve
command for the request. A new instance gets the label set on the rent form
whichever way approves it. The browser way takes your account key: open
Approve with your account key and choose your account.seed file or paste
its line. Before anything is signed, the form states the most the restore can
charge (You authorize a charge of at most …). Approve then:
- checks that the key is one of this account’s and the one the backup was made for;
- signs that charge with the account’s billing key and starts the restore, or the new instance;
- waits up to 5 minutes for the destination host’s restore key, unwraps the backup’s data key with your recovery key and wraps it again for that host, then authorizes the restore;
- forgets the key, whatever the outcome, and the page shows the restore’s progress.
Keep the page open until it says the restore goes on without it; the browser asks before you leave meanwhile. If it was interrupted, approving again on the page, or with ghost or the desktop app, carries on with the restore that started, without signing or charging it again.
A backup made before the account moved to a new account key needs the account key it was made with, which the page does not take: the page says so, and ghost can approve it with that key (see Restoring after an account key migration).
ghost account approve REQUEST_IDghost account approve REQUEST_ID --yes- The first command shows the request in your CLI and prints what it costs.
- The second approves it with
--yes. - The CLI stays running until authorization completes. If it is interrupted, repeating the same command resumes the admitted job without creating a second charge. Progress remains visible on the website.
The desktop app opens the same request from the page’s Open in Gigahost desktop.
- The restore-key authorization happens on your side, in the browser, the CLI or the app; it does not share your recovery private key. For a hosted restore, the client unwraps and rewraps only the small backup data key locally. The account key and private recovery key are never sent to Gigahost or to the hypervisor.
- Unstarted approvals expire after 15 minutes.
- When the approval is not accepted, the page says why and that nothing was charged. Approving again once the cause is gone still works until the request expires. The page keeps checking after a lost connection.
- The page,
backup restoreandinstance create --backupof a hosted backup wait at most 5 minutes (ghost’s--authorization-timeout-seconds, 300) for the destination host’s key offer and authorize no offer that comes later or has expired. The job they started goes on, and approving again resumes it; ghost’s--jsonerror names it. - An instance created from a hosted backup waits up to 15 minutes for its restore to be authorized; see Delete for deleting it meanwhile.
Creating an instance from a backup
Section titled “Creating an instance from a backup”A backup’s page (/backups/BACKUP_ID) offers Choose an offering, which
opens Capacity with only the offerings that can take the backup
(/?backup=BACKUP_ID). The rent form on an offering’s page lists only the
backups it can take, each with its restore charge. Creating an instance from a
local backup is direct; from a hosted one it opens an
approval page.
ghost catalog offerings --for-backup <BACKUP_UUID>ghost instance create \ --offering '<OFFERING_ID>' \ --backup <BACKUP_UUID> \ --waitThe first command finds an offering that can take the backup, and the second
creates the instance with --backup in place of --image. --for-backup
reads your backup, so unlike the rest of the catalog it needs your account key.
You can create a new instance from a backup instead of installing an OS.
Which offerings can take a backup
Section titled “Which offerings can take a backup”- The selected root disk needs to be at least the backup’s disk size.
- The size needs the memory the backup’s operating system needs (1 GiB for Ubuntu 26.04).
- Hosted backups can restore onto any architecture-compatible offering. A local backup can only use capacity on the physical host that stores it.
--for-backupkeeps the offerings that take the backup’s kind (a VM’s or a container instance’s backup), with a large enough root and, for a local backup, with that host among theirhost_ids; Gigahost still checks the architecture and the memory the backup’s operating system needs (1 GiB for Ubuntu 26.04) when you create.--host <HOST_UUID>alone keeps the offerings that can place an instance on one host. Gigahost applies both, as itsminimum_root_disk_bytesandhost_idfilters.- An offering whose hosts do not include a local backup’s host gets
backup_host_mismatch, which names that host and its location. - While that host is full or takes no new instances, creation from the backup
gets
capacity_unavailable, oroffering_unavailableif it was the offering’s only host.
What the new instance gets
Section titled “What the new instance gets”- It keeps the restored system’s users and SSH keys, so the SSH-key and
startup-command options are unavailable with
--backup. - Anything else the new instance needs can go in a
--cloud-init-file, which runs once at its first boot. - Gigahost supplies the new network assignment and hostname and boots only after restore finishes.
- It starts with the tags the backup’s instance
carries when it is created, unless
--tagnames others or--no-tagsasks for none; on the website, tags typed in the rent form take their place. - At its first boot the new instance also gets new SSH host keys and, on
systems with systemd, a new
/etc/machine-id.
Unavailable and lost local backups
Section titled “Unavailable and lost local backups”A local backup is kept on a drive of its host.
- When the host is missing the drive (the backup pool) that holds it, the
backup shows as Unavailable (
unavailable), with what the host found in anunavailablecolumn (in JSON the backup’sunavailableobject). It cannot be restored, nor an instance made from it: Gigahost answersbackup_pool_unavailable. Keeping it costs nothing until the host has the drive back. - Once the drive is back, the host checks that the backup’s data is still there before it can be restored again and its storage is charged again.
- A backup whose data is gone then shows as Lost (
lost): it can never be restored, costs nothing more from when the drive went missing, and you are notified.ghost backup deleteremoves it from your list.
Deleting a backup
Section titled “Deleting a backup”ghost backup delete <BACKUP_UUID> --yes --wait- Completed backups remain in their selected storage until you request deletion.
- Deletion is a background job and keeps an audit tombstone after storage confirms removal.
- A backup deletion runs beside the instance’s other jobs, and several deletions run at once.
- Deleting an instance does not delete its backups; see Delete.
Restoring after an account key migration
Section titled “Restoring after an account key migration”ghost \ --seed-file "$HOME/.config/ghost/account.next.seed" \ --recovery-seed-file "$HOME/.config/ghost/account.seed" \ backup restore <BACKUP_UUID> --yes --waitAfter migrating an account to a new account
key, you authenticate with the new
account key and select the older account key only when restoring a backup
encrypted to its recovery key. The active --seed-file still authorizes the
new restore charge. Here the replacement is account.next.seed, and the older
account key is still the default account.seed that ghost key generate
created.
A hosted backup whose key does not match the account key is stopped before
anything is sent, with recovery_key_mismatch and the fingerprint of the key
the backup was encrypted for:
- without
--recovery-seed-file, the message says that a backup made before an account key migration needs the account key it was made with; - with it, that the given account key does not match.
ghost key inspect shows an account key’s recovery_key_fingerprint.