hetshield

The Hetzner snapshot limit: 30 per account, how to count them and what to do at the wall

Hetzner Cloud allows 30 snapshots across the whole account. Count yours, price them, prune with a script, request a higher limit, or hold a copy elsewhere.

9 minute read by Dominik Geimer

The default Hetzner Cloud snapshot limit is 30, and it applies to the whole account, not to each server and not to each project. Ten servers with three snapshots each already use all of it. A retention script that creates a snapshot every night and never deletes one will hit the limit within a month, and it will do so on the night you wanted the snapshot most.

This guide covers what counts toward the limit, how to see your current usage, what the snapshots cost, a pruning script you can adapt, how to ask Hetzner for more, and when a higher limit is the wrong fix.

What the limit covers

Hetzner's backups and snapshots FAQ gives the limit as 30 snapshots across all projects of one account. Two consequences are easy to miss:

  • Projects do not help. Projects separate API tokens, team members and resources. They share one account, one invoice and one snapshot quota. Splitting servers into a second project does not buy a second 30.
  • It is not per server. A server with 12 snapshots leaves 18 for everything else you run.

Backups are a different feature. Hetzner Backups are automatic, keep seven slots per server, and cost 20 percent of the server price (billing FAQ). They are bound to the server and are deleted with it. Snapshots are manual, are kept until you delete them, and are the resource the 30 limit is about. If you are choosing between the two, the offsite backup guide has a comparison table.

The Hetzner Cloud API treats snapshots, backups and system images as one resource type, image, told apart by the type field (system, app, snapshot, backup). That is why every command below filters by --type snapshot.

Count what you have

Install the hcloud CLI and set a token for the project. A read-only token is enough for everything in this section.

export HCLOUD_TOKEN=...   # read-only token for one project

# How many snapshots does this project hold?
hcloud image list --type snapshot -o json | jq length

# Newest first, with size and source server
hcloud image list --type snapshot --sort created:desc \
  -o columns=id,description,image_size,disk_size,created,created_from

Because the limit is account-wide, run the count once per project and add the numbers. People who forget a project they set up for an experiment are the ones surprised at 30.

The created_from field records which server the snapshot came from, so you can see who is using the quota:

hcloud image list --type snapshot -o json \
  | jq -r 'group_by(.created_from.name // "(server deleted)")
           | .[] | "\(length)\t\(.[0].created_from.name // "(server deleted)")"' \
  | sort -rn

The last bucket matters most. Deleting a server does not delete its snapshots, so snapshots whose source no longer exists are the usual first thing to remove.

If you call the API directly instead of using the CLI, remember that the list is paginated and returns 25 items by default (OpenAPI spec). Count from page one only and you will report a number that is too low. Follow meta.pagination.next_page until it is empty:

page=1; total=0
while [ -n "$page" ] && [ "$page" != "null" ]; do
  resp=$(curl -s -H "Authorization: Bearer $HCLOUD_TOKEN" \
    "https://api.hetzner.cloud/v1/images?type=snapshot&per_page=50&page=$page")
  total=$(( total + $(echo "$resp" | jq '.images | length') ))
  page=$(echo "$resp" | jq -r '.meta.pagination.next_page')
done
echo "$total snapshots in this project"

What the snapshots cost

The limit is a count, but the bill is by size. Snapshots are billed per gigabyte per month on the compressed size of the image. The API reports it as image_size, described in the spec as "the value relevant for calculating costs for the Image". disk_size is the size of the disk it contains and is not what you pay for.

At the time of writing the price is about 0.0143 euro per GB per month, but Hetzner changes prices, so check the billing FAQ before you plan around it. To see what your own snapshots add up to:

hcloud image list --type snapshot -o json \
  | jq '[.[].image_size // 0] | add | . * 100 | round / 100 | "\(.) GB billed"'

Multiply that by the current per-GB price. For most small servers the answer is cents per snapshot, which is why the count, not the money, is the first constraint you hit.

Label snapshots so you can prune them safely

A retention policy needs something to select on. Description text is fragile; labels are not. Create every snapshot with a label for the server and the reason:

hcloud server create-image web-1 --type snapshot \
  --description "web-1 before PHP upgrade 2026-11-02" \
  --label server=web-1 --label kind=pre-change

Snapshots of a running server are crash-consistent, the same state the disk would be in after a power cut. For a database that is usually recoverable, but if you need a clean state, stop the writes or take a database-level dump first.

Now a pruning script. This one keeps the three newest pre-change snapshots per server and prints the rest, so you can read the list before anything is deleted:

hcloud image list --type snapshot --selector kind=pre-change -o json \
  | jq -r 'group_by(.labels.server)
           | .[] | sort_by(.created) | reverse | .[3:] | .[]
           | "\(.id)\t\(.created)\t\(.description)"' \
  > prune-candidates.tsv

cat prune-candidates.tsv

When the list looks right, delete them:

cut -f1 prune-candidates.tsv | xargs -r -n1 hcloud image delete

Two safety notes. First, the --selector filter is what keeps this script away from snapshots you did not label; never run a delete over an unfiltered list. Second, snapshots you want to keep forever can be given delete protection (hcloud image enable-protection <id> delete). A protected image cannot be deleted until you remove the protection, which makes it safe against a mistake in a script.

Run the dry-run half from cron or a CI job and look at it for a few weeks before you let anything delete on its own. A pruner that quietly deletes the wrong snapshot is worse than one that fails at 30.

Ask Hetzner for a higher limit

The limit can be raised on request. According to Hetzner, you need to have been a customer for at least a month with a paid invoice before they will raise it. New accounts, or accounts that have only just started paying, cannot get an increase yet.

The request goes to Hetzner support, not through the API. Say what you will use the snapshots for; a plan for pruning is more convincing than a bare number. Treat the answer as a convenience rather than a plan, and keep these points in mind:

  • A higher limit delays the wall without moving it. If the real problem is that nothing prunes, the new limit fills too.
  • More snapshots cost proportionally more, as the section above shows.
  • Every extra snapshot is one more thing that lives inside the same account.

When 30 is the wrong thing to fix

If you are near the limit, check what the snapshots are for. In practice they fall into three groups, and only one of them is a good use of the quota.

Snapshot purpose Right tool Keep how many
Rollback point before a risky change Snapshot The last two or three per server, delete after the change is proven
Rolling "restore to last night" Hetzner Backups (7 slots per server) Automatic
Long retention, compliance, "we might need this in six months" A file or image held outside the account As many as your storage allows

Snapshots as a long archive are what push people to 30. They are the wrong tool for that job for a second reason beyond the count: a snapshot is a resource of the Hetzner account. If the account is locked or terminated, the snapshots go with it, whatever the limit. The cases and the terms are laid out in Hetzner account locked: what actually happens to your data, and the planning side is in the disaster recovery plan.

One more limit hides here. Volumes are not part of a snapshot or of a backup. If a server keeps its data on an attached volume, 30 snapshots of it still contain none of that data. See Hetzner snapshots do not include volumes for how to find the servers at risk.

Move long retention out of the account

If the snapshots you cannot bring yourself to delete are the long-retention ones, the better move is to hold that copy somewhere else and then free the slot. There are three honest ways to do it.

File-level backups. Tools such as restic and Borg write encrypted, deduplicated backups of directories to S3-compatible storage or another host. They are the best answer for data that changes daily and for restoring a single file, and they take no snapshot slot. They do not recreate the machine: you still have to rebuild the operating system and its configuration first.

Your own image. You can make a raw disk image from a Hetzner server yourself. The manual route, with its trade-offs between downtime and consistency, is described step by step in Can you download a Hetzner Cloud snapshot?. A raw image compresses well and can be kept like any file. Restoring it is covered for Proxmox, KVM and libvirt, VMware, Hyper-V and VirtualBox, and back onto a new Hetzner server.

A service that does it for you. hetshield is one option. It needs only a Hetzner API token, runs without downtime, and only snapshots the source server: it is never rebooted, and the cloned copy is never booted as your system. You download a compressed raw image. In our measurement a 40 GB disk was read in 1:52, and a full export takes about nine minutes end to end. It costs $29 flat plus VAT and is refunded if the export does not finish. Volumes are excluded, as with every image-level method. The documentation describes what is in the image and how to restore it. Because it works from a snapshot of the running server, keep some room under the snapshot limit when you run it.

Whichever you pick, test the restore once. A copy you have never booted is a hope rather than a backup.

A checklist for this week

  1. Run the count in every project and add the numbers. Write the total down.
  2. Delete snapshots whose source server no longer exists, after checking each one.
  3. Start labelling new snapshots with server= and kind=.
  4. Put the dry-run pruning list on a schedule and read it for a few weeks.
  5. Turn on Hetzner Backups for anything that needs a "last night" restore, so it stops competing for snapshot slots.
  6. Move anything you want to keep for months out of the account, and boot it once to prove it works.
  7. If you still need more than 30, ask support, and state your pruning plan in the request.

The limit is a nuisance, but it also does a useful job: it forces the question of which copies you actually need and where they live. Answer that, and 30 is usually plenty.

Keep reading