Why disks in Hetzner Cloud Volumes hit the limit
The volume is full — and the first to notice this is not monitoring, but the application.
A block volume has a limit: when free space is down to a few percent, the file system begins to fragment writes, the I/O queue grows, and write response time increases severalfold — this is write degradation that shows up in load graphs before it does in alerts.
The service is still running, but logs, sessions, temporary files, and database journals are written with delay, and once space is completely exhausted, the kernel switches the partition to read-only mode — and the database returns errors on every transaction.
A separate trap is that the volume and the file system scale separately. Increasing a block volume by itself does not add space: the partition remains the same size, and free space will not appear until the partition and file system are expanded. Diagnosing this combination usually takes more time than the fix itself.
Manual expansion almost always means service downtime. You need to stop the application, unmount the volume, change the partition, run a file system check, mount it back, and make sure the data is intact.
On a loaded database, this is a window of several tens of minutes at night, plus the risk of a partitioning error and a guaranteed availability hit.
We explain how this is addressed: expansion without downtime, when the volume grows on the fly and the file system picks up the new size without stopping the application.
And data tiering — hot datasets remain on the block volume, while cold and static data move to object storage, so the volume stops being the only place where space runs out.
Expanding Volumes and snapshots without service downtime
As long as data resides on a server's local disk, any change — of size, recovery point, or migration — requires stopping the service.
Moving to managed volumes and object storage Hetzner decouples the compute node from the data: the instance can be recreated or replaced, while volumes and storage contents remain in place. Below are four effects visible in operations.
Growing a volume on the fly
The volume size is changed as a separate operation, without restarting the instance: the node keeps serving requests, and the file system is expanded on a running machine.
This eliminates the scenario where "space ran out in the evening, but the window for stopping is only on the weekend."
Recovery from snapshots
A snapshot captures the state of the block as a whole, so returning to a previous point means creating a new volume from the snapshot and attaching it.
Instead of a cold deployment of an archive with unpacking, you get attachment of a ready block: recovery is reduced from hours to minutes, while the source volume remains untouched for analyzing the cause of the failure.
The remaining two effects are backup and operations automation. Uploads to object storage run on a schedule and append only changes, while retention rules themselves remove outdated generations, so the archive does not grow indefinitely.
Snapshot schedules, rotation, and regular recovery testing are described in configuration: a node failure becomes recreation of the instance with volume attachment, without manual data recovery.
Storage modes: block volumes, object storage, and local
The difference between storage modes shows up during failures and load growth, not in normal operation.
A block volume in Hetzner Cloud is mounted to a server and survives its recreation, object storage serves files over the network, and a local disk lives only as long as the server itself. Below are the criteria by which we separate data.
Selection criteria
The first question is whether file semantics are needed: partial writes, renaming, locking. If the application works with directories and access permissions, we use a block volume. For archives and infrequent exchange, object storage is sufficient.
| Option | When it fits | Limitations |
|---|---|---|
| Block volume | Databases, application directories, working files | Attaches to one server; tied to an availability zone; size only grows upward |
| Object storage | Backups, uploads, static assets, exchange between services | No file semantics; higher latency on frequent small operations |
| Local disk | Cache, temporary files, intermediate calculations | Data is lost when the server is recreated; no separate snapshot; capacity is set by the plan |
Typical bottlenecks
The most common mistakes are two: mounting one volume to several servers and corrupting the file system, or putting a database into object storage, where latency on each small operation adds up to noticeable seconds. We separate data by modes in advance so this does not surface when load grows.
Implementation stages: from load audit to handover of procedures
We work in iterations: each stage ends with an artifact that can be verified. The order is not decorative — if the data placement scheme is not based on measurements, failure testing will expose this in production.
Audit and design
- Load audit — we capture a profile over a long period: write volume and pattern, read share, peaks, growth rate. The output is a calculation of what we keep on volumes and what we move to object storage.
- Data placement scheme — we distribute databases, files, and backups across volumes and buckets, set size with headroom for growth and snapshot points. We separately record what lives together with the server and what is independent of it.
- Access separation — keys and roles separately for applications, services, and people; permissions only for the needed operations with specific buckets; secrets are not stored alongside code.
Implementation and acceptance
- Configuration — we create Hetzner Cloud Volumes volumes and object storage, configure mounting, encryption, backup schedules, and lifecycle policies: how many versions to keep and when to free up space.
- Failure testing — we restart the node, overflow the volume, drop a copy: we check whether the service comes back up on its own and how long recovery from a snapshot takes.
- Handover of procedures — storage scheme, rotation rules, on-call actions for overflow, and instructions for rolling back to the previous snapshot.
Configurations, schemes, and access policies after implementation
After implementation, the customer's team is left not with a "working infrastructure" as a black box, but with a package by which it can be maintained, expanded, and restored without us. Below is exactly what is handed over and in what form.
What is included in the handover package
- Storage configuration — descriptions of Hetzner Cloud Volumes and Object Storage buckets: size, mount point, file system, server connection parameters. All as files, not settings manually configured in the panel.
- Placement scheme — a map: which volume and bucket serve which service, where state data is stored, where backups are, and how traffic flows between them.
- Access policies — roles and keys: who reads and writes and from which network, which keys are read-only, where prefix restrictions apply, and how rotation is performed.
- Snapshot schedule — intervals, retention depth, what automatic snapshots cover, and what cross-location copying covers.
- Recovery instructions — the sequence: from which snapshot, in what order, how to verify integrity and bring the service back online.
- Testing procedure — how often we deploy a snapshot in the test environment and what we do if there is a discrepancy.
- Observability scheme — volume fill metrics, alerts about backup failures and access errors.
The package lives in a repository alongside the infrastructure configuration: changes go through review, history is preserved, and a new engineer joins the environment using documentation, not stories.
Case study: an image registry migrated without service downtime
The product team's image registry was hitting the volume size limit. New builds added layers, no one deleted old manifests and tags, and usage grew faster than the volume could be expanded.
It ended predictably: writes failed, the on-call engineer stopped the registry, manually migrated data, and switched the mount point — hours of downtime, and recovery was blind, without a proven procedure.
Storage was separated by purpose: metadata and working directories remained on a block volume that expands on the fly, while image layers were moved to object storage Hetzner.
A retention rule keeps a fixed number of latest builds per tag and removes the rest — the volume stopped growing on its own.
Migration without service downtime
The switch was done through a single registry address with a short TTL: while build environments were uploading images from the old storage, data was already being synchronized to the new one.
The old environment was switched to read-only, discrepancies were reconciled, and it was decommissioned last — no environment received an error during upload.
The registry volume was reduced by about half due to cleaning up old builds, manual migrations disappeared from regular work, and volume expansion happens under load.
Planned recovery was rehearsed on a copy: deployment from a snapshot took about twenty minutes instead of the previous four to six hours of manual operations. Alerts monitor growth rate and capacity forecast — we learn about risk in advance, not at the moment of failure.
What to do if storage is already deployed and contains data?
Storage migration on a live service is not done head-on: while traffic is flowing, Hetzner Cloud Volumes block volumes and object storage keep changing, and any copy becomes stale the moment it is created.
Therefore, we build migration without downtime as a parallel scheme, not as a stop-and-migrate: the new configuration is brought up alongside the old one, the application writes to both places, and reads are switched over only after reconciliation.
We verify integrity by convergence, not by eye: block checksums, number and size of objects, last write time in each branch. Discrepancies are analyzed before switching — the delta is appended from the change log, not migrated blindly. Until reconciliation converges, traffic reads from the old scheme.
Backward compatibility relies on old paths and mount points remaining operational: the application receives new addresses through environment variables, not through code changes. Then rollback is reverting one variable and restarting, not a second migration.
We fix the rollback plan before starting: the old scheme is not decommissioned until the new one has completed the full cycle of "write — read — backup — recovery." Downtime during such a transition is measured in seconds of read switching, not hours of copying; the main work happens in the background, on a live service.
Technical concerns: integrity, access, and fault tolerance
Engineers' reliability objections are almost always about verifiability, not distrust of the platform. Below are the ones that most often come up when migrating data to Hetzner and separating access between services.
How to preserve data integrity during migration?
We detach volumes from the application or switch the database to read-only — the snapshot is taken consistent, not with data in flight. After migration, we compare checksums, test-mount, and check the file system before switching traffic.
How to separate service access rights?
Each service gets a separate key, limited to its own object storage container and set of operations: an application that reads static assets does not need write and delete permissions. We attach volumes with the required mount flags, and for critical data — read-only.
What happens if a node fails?
Volume snapshots and object versioning hold a recovery point independently of the server state. We rehearse recovery from a snapshot in the test environment in advance — the actual recovery time is known, not assumed.
How are encryption and access auditing arranged?
Data is encrypted at rest and in transit, keys are stored outside the application configuration. Requests to object storage are written to an access log — it shows who read the container and when, and alerts for anomalies can be configured.
Let's discuss the task: we'll put together a storage scheme and migration plan
The migration plan is assembled from input data, not from general considerations. Describe the problem statement: which services write and read data, daily and peak volume, share of small objects, requirements for durability and geography.
Using these numbers, we estimate the scope of work and understand where an intermediate environment is needed and where switching on the fly is sufficient.
We separately clarify what most often slows down migration: maintenance windows, access to the control panel and API, who owns DNS and certificates, and whether there is a hard requirement for compatibility with a familiar object storage interface. If some inputs are unknown — no problem, we'll go over them in the first conversation.
The work plan will include:
- a scheme for splitting across Hetzner Cloud Volumes and object storage buckets with permissions and names;
- a version retention rule: how many latest copies we keep, what moves to the cold storage class, and what is deleted;
- a step-by-step sequence of work — from the test environment to switching the production workload;
- checkpoints after each step: how we make sure data has converged and the service responds;
- a rollback plan: at what point and by what actions we return to the previous scheme;
- a set of metrics and alerts: volume fill, write error rate, response latency;
- final documentation — scheme, policies, and instructions for the on-call shift.
Describe the task in free form: we'll come back with a scope estimate, a migration plan, and an agreed sequence of work.







