Written for: Developers and platform teams running self-hosted PostgreSQL or MySQL on block storage and deciding how to monitor, size, back up, and recover database volumes.
Use one dedicated database volume by default. Monitor capacity, time-to-full, latency, IOPS, throughput, queueing, and engine-level storage signals. Split logs or temporary work only when measurements justify it. Treat the volume as active storage, not a backup, and keep database-aware recovery independent from the active volume.
Database storage on block volumes means placing a self-hosted database's persistent files on attached disk-like storage instead of making the VM's root disk the only home for database state.
For most small teams, a practical starting point is one dedicated database volume, enough growth headroom, database-aware backups, and monitoring that connects Linux storage signals with database behavior. Split data, transaction logs, or temporary work across additional volumes only when measurements or recovery requirements justify the extra complexity.
At Raff, this architecture usually means a Raff VM for the database host and a Raff Volume for persistent disk-like database state. Teams that do not need host-level database control should also compare Raff Managed Databases, because a block volume separates storage from the VM lifecycle but does not make PostgreSQL or MySQL managed.
Database storage on block volumes: quick decision
Situation
Better starting point
Development or disposable database
VM system disk may be enough
Production self-hosted PostgreSQL/MySQL
One dedicated database volume
Database storage grows faster than VM compute
Dedicated volume
Measured WAL/redo contention
Consider a separate log volume only after testing
Large temporary jobs threaten primary data capacity
Consider a separate temporary-work volume
Team does not want to own filesystem, patching, backups, and recovery
Managed database
Need root access, custom packages, or exact storage layout
Raff VM + Volume
The default should be simple. A storage layout is useful only if your team can monitor, back up, restore, and explain it during an incident.
Why separate database storage from the VM system disk
A database writes more than table rows. Its active storage may include:
table and index files;
transaction logs such as PostgreSQL WAL or MySQL redo logs;
temporary files;
engine metadata;
control files;
replication-related state;
maintenance working space.
If all of that shares the VM root disk with the operating system, application logs, package updates, and other services, one storage problem can affect the whole host.
A clearer layout is:
Text
Raff VM system disk
-> OS
-> database packages
-> configuration
-> service logs
Raff Volume
-> database persistent files
Independent database backup / PITR path
-> historical recovery
The value is lifecycle separation:
database capacity can grow without forcing a compute resize;
the VM can be rebuilt without treating the root disk as the only database copy;
database storage gets its own alerts and capacity plan;
the operating-system filesystem is less exposed to database growth;
recovery responsibilities become easier to document.
A dedicated volume is still primary active storage. It is not a backup.
One dedicated database volume is usually the practical default
It is tempting to create separate devices for data, indexes, WAL/redo, temporary files, and backups from day one. For a small team, that often increases operational surface before it solves a measured problem.
Layout
When it fits
Main trade-off
Database on root disk
Low-risk or temporary environments
OS and database share capacity/failure pressure
One dedicated database volume
Most self-hosted production databases
Mixed database I/O shares one device
Separate data and transaction-log volumes
Measured write/log contention or distinct capacity needs
More mounts, alerts, recovery ordering, and configuration
Separate temporary-work volume
Large sorts/imports/rebuilds threaten primary data space
More storage to operate and clean up
Managed database
Host-level database storage should not be your responsibility
Less OS/filesystem control
Choose a second storage boundary only when the benefit is clear.
Good reasons include:
measured I/O contention between data and transaction logs;
materially different growth rates;
a temporary workload that can exhaust primary database storage;
a recovery or maintenance procedure that benefits from separation;
a database architecture that already has operators who can manage multiple paths safely.
Poor reasons include generic claims that separate disks are always faster or that production databases must have many volumes.
Capacity planning should use headroom and time-to-full
A database volume can look healthy by percentage used and still be heading toward an incident quickly.
Track:
allocated capacity;
current used/free space;
database data size;
index size;
WAL, redo, and binary-log growth;
temporary-file growth;
migration or index-build requirements;
daily/weekly growth rate;
estimated time to full;
expansion lead time;
recovery headroom.
A useful planning model is:
Text
current data + indexes
+ transaction-log headroom
+ temporary / maintenance work
+ expected growth
+ recovery safety margin
= required working capacity
The rate of change matters more than one static percentage.
A volume at 70% utilization with stable monthly growth may be comfortable. The same 70% during a large migration that is adding several GiB per hour can be urgent.
Capacity alerts should answer an operational question
A useful alert is not simply "disk is 80% full." It should help answer:
how quickly is usage growing?
what is creating the growth?
when will the safe headroom be exhausted?
can capacity be expanded before that point?
is the growth expected or caused by a broken retention/replication/maintenance process?
A resize can solve a capacity deadline. It does not solve runaway logs, failed archiving, abandoned temporary files, or a workload that will immediately consume the new space.
Database storage monitoring needs device and engine signals together
For block-backed database storage, track at least five infrastructure dimensions:
Signal
What it tells you
Capacity
How much usable filesystem space remains
Latency
How long reads/writes take
IOPS
How many I/O operations are completing
Throughput
How many bytes are moving per second
Queueing / wait
Whether demand is arriving faster than storage completes it
Interpret these together.
High IOPS with low latency may be healthy. Moderate IOPS with rising latency and sustained queueing may indicate saturation. High throughput during a planned backup may be expected; the same pattern during peak customer traffic may explain application latency.
The useful diagnostic question is:
Which database activity is producing storage pressure, and is the storage layer completing that work within the workload's latency budget?
PostgreSQL storage monitoring should connect WAL, checkpoints, and I/O
PostgreSQL keeps the database cluster under PGDATA and uses WAL for durability and recovery. Monitor the database and filesystem together.
Useful PostgreSQL evidence includes:
pg_stat_io where supported by the deployed PostgreSQL version;
pg_stat_wal for WAL generation and write/sync behavior;
checkpointer statistics;
database-level temporary-file activity;
long-running transactions;
archiving state where WAL archiving is used;
replication-slot or replica state where it affects WAL retention;
filesystem capacity and latency for the database paths.
Examples of patterns worth investigating:
WAL growing much faster than normal;
storage latency rising during checkpoints;
temporary files consuming unexpected capacity;
a replication or archive problem retaining more WAL than planned;
index creation or schema maintenance consuming temporary headroom;
long-running transactions delaying cleanup or maintenance.
Do not split WAL onto another volume merely because PostgreSQL supports separate paths. Do it when measurements show that the additional storage boundary improves the workload and your recovery procedure covers it.
MySQL and InnoDB monitoring should connect redo, temporary work, and filesystem pressure
A MySQL data directory can contain InnoDB tablespaces, redo files, temporary data, binary logs, and other server-managed files.
Useful MySQL evidence includes:
Performance Schema file-I/O summaries;
InnoDB pending reads/writes;
redo-log and checkpoint progress;
buffer-pool behavior;
binary-log growth and retention;
temporary-table/filespace growth;
filesystem capacity, latency, throughput, and queueing.
Do not treat high device utilization as the diagnosis by itself.
The storage pressure may come from:
foreground queries;
flushing/checkpoints;
backup activity;
imports;
index or schema operations;
large temporary work;
insufficient memory causing more disk reads;
binary-log or retention behavior.
Find the workload cause before changing database or storage settings.
Operational insight from Raff: when storage pressure appears, separating the database volume is useful only after the team identifies whether capacity, latency, temporary work, or transaction-log growth is actually driving the incident.
A block volume can be attached in the cloud control plane while the guest operating system still has a mount or startup problem.
Production documentation should record:
filesystem type;
stable device identifier or UUID;
mount path;
database service ownership/permissions;
boot behavior;
dependency between the mount and database service startup;
expected behavior when the volume is unavailable.
One dangerous failure mode is:
Text
expected database mount missing
-> mount directory exists on root disk
-> database/service starts against the wrong path
-> new state is written somewhere unintended
For a database, the exact failure behavior depends on engine configuration and directory structure, but the principle is the same: the service should not silently start against an unintended empty path.
Verify storage mounts before starting or restarting stateful services after maintenance.
A block volume does not replace database-aware backups
A volume stores the current active state, including bad state.
It can preserve:
accidental deletes;
destructive schema changes;
corrupted files;
application-written bad data;
ransomware-encrypted state;
mistakes made by privileged operators.
That is why recovery needs an independent historical path.
A useful control map is:
Control
Main job
Block volume
Active persistent database storage
Volume/VM snapshot
Infrastructure recovery point for selected scenarios
Database backup
Engine-aware historical recovery
PITR / transaction-log recovery
Recover toward a selected historical point
Replica / HA
Service continuity for selected failures
Restore test
Prove the recovery path works
Do not call a replica a backup. Do not call a persistent volume a backup. Do not assume a block-level snapshot is automatically database-consistent without an engine-aware procedure.
A storage design is incomplete until the team knows what happens when each layer fails.
Failure
Typical recovery path
VM OS failure, volume healthy
Replace/rebuild VM and reattach/reconnect storage according to documented platform workflow
Accidental row/table deletion
Database backup or PITR
Bad schema migration
Rollback or historical database recovery
Filesystem/database corruption
Known-good database recovery point
Volume nearing full
Stop avoidable growth, restore headroom, expand when appropriate, fix root cause
Volume unavailable/lost
Restore database to replacement storage
Incorrect mount/permissions
Restore expected mount and ownership, then validate database state
Complete host + storage loss
Independent database backup + rebuild runbook
The team should also know the recovery order:
Text
restore/provision storage
-> restore database state
-> validate database
-> reconnect application
-> validate business workflows
-> verify new backups/recovery coverage
Recovery is not complete merely because the database process starts.
Managed databases change the storage responsibility boundary
A dedicated block volume is appropriate when the team wants a self-hosted database and accepts host-level storage ownership.
That ownership includes:
filesystem layout;
mount configuration;
capacity forecasting;
database storage telemetry;
OS and database patching;
backup design;
restore testing;
replication/HA when needed;
incidents.
If the application does not require root access, custom packages, direct filesystem access, or a topology outside the managed-service boundary, a managed database can reduce that operational surface.
Raff Volumes provide block storage for workloads that need persistent disk-like storage attached to Raff VMs. Current Volumes pricing is $0.08/GB-month.
A simple database architecture is:
Text
Application
-> private/restricted network
Raff VM running PostgreSQL/MySQL
-> Raff Volume for persistent database state
-> database-aware backup / recovery path
Use the live Volumes product page as the source of truth for current size limits, attachment behavior, resize behavior, snapshots, and other provider-specific capabilities.
For teams that want less host-level database ownership, compare Raff Managed Databases. For VM-level recovery controls that complement, but do not replace, database-aware recovery, review Raff Data Protection.
If compatible database backup artifacts need an independent S3-compatible destination, Raff Object Storage can be considered as part of the backup architecture.
Database volume readiness checklist
Before putting a production database on a block volume, confirm:
The volume has one documented purpose and owner.
The database state is intentionally separate from the VM root disk.
Filesystem type, mount path, stable identifier, permissions, and startup dependency are documented.
The engine's data, transaction-log, temporary, and tablespace paths are known.
Current data and index size are measured.
Growth rate and time-to-full are monitored.
Maintenance and migration headroom are included in capacity planning.
Capacity, latency, IOPS, throughput, and queueing are visible.
Engine-level storage signals are correlated with device metrics.
Backups are independent from active database storage.
Snapshot consistency assumptions are documented.
RPO and RTO are defined for important data.
Restore testing includes database startup and application validation.
Recovery paths exist for deletion, corruption, migration failure, and infrastructure loss.
The team has explicitly chosen self-hosting over a managed database responsibility model.
Common mistakes
Treating the volume as a backup
A block volume is active state. It reflects bad writes and deletions too.
Splitting storage before measuring contention
Additional volumes increase mounts, monitoring, configuration, backup, and recovery complexity. Add them for a measured reason.
Monitoring only percentage used
Track growth rate and time-to-full so the team knows how quickly the condition is changing.
Watching Linux metrics without database context
Storage latency is more useful when correlated with WAL/redo, checkpoints, query workload, temporary files, backups, and migrations.
Keeping backups on the same failure path
Historical recovery should not depend entirely on the active database storage.
Hard-coding mutable product pricing into architecture guidance
Use the live Raff Volumes and pricing pages for current commercial values.
Conclusion
Database storage on block volumes works well when the volume is treated as an explicit state boundary, not merely extra disk space.
For most small teams self-hosting PostgreSQL or MySQL, start with one dedicated database volume. Monitor capacity, growth rate, latency, IOPS, throughput, queueing, and the database signals that explain those changes. Add separate log or temporary-work volumes only when workload evidence justifies the complexity.
Then design recovery independently from active storage. A volume can make compute and storage lifecycles easier to manage, but database-aware backups, PITR where required, and tested restores are what make the data recoverable.
It places a self-hosted database's persistent files on attached disk-like storage separate from the VM system disk, creating a clearer capacity and lifecycle boundary for database state.
Should a database use one volume or separate data and log volumes?+
Most small teams should start with one dedicated database volume. Separate data, transaction logs, or temporary work only when measurements, growth patterns, or recovery requirements justify the added complexity.
Which storage metrics matter most for a database volume?+
Monitor capacity, growth rate, time-to-full, latency, IOPS, throughput, and queueing, then correlate those signals with database checkpoints, WAL/redo, temporary files, queries, backups, and maintenance.
How should PostgreSQL storage be monitored?+
Combine filesystem/device metrics with PostgreSQL signals such as pg_stat_io where supported, pg_stat_wal, checkpointer statistics, temporary-file activity, transaction age, archiving, and replication state.
How should MySQL storage be monitored?+
Combine device metrics with Performance Schema file-I/O summaries, InnoDB pending I/O, redo/checkpoint behavior, buffer-pool activity, binary-log growth, and temporary-space usage.
Do block-volume snapshots replace database backups?+
No. A snapshot can support selected infrastructure rollback scenarios, but databases still need engine-aware backups or point-in-time recovery where required, plus tested restores.
When should I use a managed database instead of a VM with a volume?+
Use a managed database when the supported service fits and reducing filesystem, patching, backup-platform, monitoring, storage, and recovery operations is more valuable than direct host-level control.
Where should I check current Raff Volume pricing and limits?+
Use the live Raff Volumes product page and pricing page as the source of truth because pricing, limits, attachment, resize, and snapshot capabilities can change independently of this guide.