Proxmox VEV · Storage FundamentalsStorage concepts
IOPS, latency, queue depth, sync vs async
What you'll learn
- Define IOPS, latency, throughput, and queue depth and how they trade off
- Understand the difference between synchronous and asynchronous writes
- Recognise the most common performance anti-patterns
- Use fio to measure baseline storage performance
Prerequisites
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-07
Why this matters in production
“The storage is slow” tickets are nearly always diagnosable with four numbers: IOPS, latency, throughput, and queue depth. Knowing what each measures — and what affects each — lets you triage in minutes instead of arguing about brand names.
The four numbers
| Metric | What it measures | Typical scale |
|---|---|---|
| IOPS | I/O operations per second | 100 (HDD) → 100 000+ (NVMe) |
| Latency | Time per operation | 1 ms (NVMe) → 20 ms (HDD) |
| Throughput | Bytes per second | 100 MB/s (single SSD) → 10 GB/s (RAID) |
| Queue depth | Number of concurrent in-flight I/Os | 1 → 32+ |
These numbers trade off. A device doing 100 000 IOPS at 4 KB each delivers 400 MB/s of throughput. Doubling IOPS at smaller block size doubles IOPS but halves throughput.
flowchart LR
A[Application issues I/O] --> Q[Queue depth: how many concurrent requests?]
Q --> D[Device: NVMe / SSD / HDD]
D --> R[Result: IOPS, latency, throughput]
Synchronous vs asynchronous writes
- Asynchronous write: the application issues the write, the kernel acknowledges it, the data sits in the page cache, eventually flushes to disk. Fast. If the host loses power between acknowledgement and flush, the write is lost.
- Synchronous write: the application issues the write, the kernel hands it to the device, the device confirms durable storage before returning. Slower (often much slower), but crash-safe.
Databases use synchronous writes to guarantee durability. Filesystem fsync() triggers
them. ZFS has its own equivalent (ZIL). Ceph RBD has its own equivalent (write journal).
Queue depth
The device’s parallelism. Most storage devices have an internal queue that allows them to process multiple requests concurrently. NVMe supports 65 535 commands per queue; SATA SSDs typically 32.
To maximise throughput, the application (or kernel) must keep enough requests in flight. A single-threaded application issuing one I/O at a time wastes the device’s parallelism.
The storage stack in Proxmox
flowchart TB
App[Application fsync/write] --> FS[Guest filesystem]
FS --> VT[VirtIO-SCSI]
VT --> QE[QEMU]
QE --> HL[Host block layer]
HL --> ZFS[ZFS / LVM / RBD]
ZFS --> PD[Physical disk]
Every layer can be a bottleneck. Performance issues are diagnosed by measuring at each layer:
- Guest:
iostat -xinside the guest. - Host:
iostat -xon the host. - Storage: ZFS
zpool iostat, Cephceph osd perf.
The most common anti-patterns
| Anti-pattern | Symptom | Fix |
|---|---|---|
| One SATA SSD for everything | Slow writes under sync | Add ZIL/SLOG device |
| Mixed workloads on one disk | Latency spikes | Separate disk for databases |
| Queue depth 1 on a fast device | Underutilised bandwidth | Increase nr_requests and use AIO |
| RAID controller with write-back cache and no BBU | Power-loss data loss | Add BBU or use ZFS direct |
| SSD with no TRIM | Slow after sustained writes | Enable discard=on on the VM disk |
| Consumer SSD with sync writes | Silent corruption on power loss | Use enterprise SSD with PLP |
Benchmarking with fio
fio is the standard Linux storage benchmark. The Proxmox host has it in the package
repositories.
apt install -y fio && fio --name=randread --ioengine=libaio --direct=1 --bs=4k --rw=randread --numjobs=4 --runtime=30 --size=1G --filename=/tmp/fiotest --group_reporting
fio --name=syncwrite --ioengine=libaio --direct=1 --bs=4k --rw=randwrite --numjobs=1 --runtime=30 --size=1G --filename=/tmp/fiotest --sync=1 --group_reporting
Production considerations
Common mistakes
- “I have an SSD, so storage is fast.” SSDs differ by 100× in IOPS; cheap consumer SSDs are slow under sustained writes.
- “Sync writes only matter if I have a database.” All workloads that care about durability (most of them) need to think about sync semantics.
- “Higher queue depth is always better.” No — it depends on the device’s ability to parallelise. Saturating queue depth on a single HDD does not help.
Key takeaways
- IOPS, latency, throughput, queue depth. Four numbers. Know your workload’s profile.
- Sync writes are limited by the slowest durable path, often the SLOG.
- Benchmarks must reflect real workloads.
Knowledge check
Knowledge check · 3 questions
Q1. A 4 KB random write workload at 50 000 IOPS delivers how much throughput?
Q2. Sync write latency is set by the slowest device in the durable path, which on a ZFS pool with a SLOG is the SLOG.
Q3. Which Linux tool is the standard for measuring storage performance?
Passing score: 75%. Answers are checked in this browser.