Usage
Common fio invocations, organized by what you're trying to learn.
IO engines
fio ships with many engines. The ones built into our binaries:
| engine | purpose |
|---|---|
psync | synchronous pread/pwrite (default) |
vsync | synchronous readv/writev |
pvsync | synchronous preadv/pwritev |
pvsync2 | preadv2/pwritev2 with flags |
io_uring | Linux io_uring (kernel ≥ 5.6; lowest-latency async) |
mmap | mmap-based file IO |
null | no-op (CPU-only, useful for testing) |
cpu | CPU-bound workload simulation |
net | network IO (via sendfile etc.) |
exec | spawn external processes per IO |
fileoperations | filecreate / filestat / filedelete / etc. |
Use --ioengine=NAME to switch. Optional engines
(libaio, libpmem, librbd, libcurl, libibverbs, …) require external
libraries — see caveats below.
Output formats
| flag | format | when |
|---|---|---|
| (default) | human-readable plain text | interactive use |
--minimal | single semicolon-separated line per job | shell parsing |
--output-format=json | JSON document | programmatic parsing |
--output-format=json+ | JSON with all per-IO samples | deep analysis (large output) |
--output-format=normal,latency | human + latency histogram | latency debugging |
--output=FILE | write to FILE instead of stdout | log capture |
Job files
For complex or repeated workloads, write a job file and pass it as the argument:
# bench-randwrite.fio
[global]
filename=/tmp/fio-test.bin
size=1G
bs=4k
rw=randwrite
ioengine=io_uring
runtime=60
time_based=1
group_reporting=1
numjobs=4
[job1]
stonewall
$ fio bench-randwrite.fio
Multiple sections can share [global] settings and run
in parallel or sequence (stonewall = sequential).
Rate limiting & latency targets
Constrain fio to a specific throughput target to test "is my device meeting SLA" rather than "what's the max IOPS":
# 10k read IOPS, 50/90/99 latency percentiles
$ fio --rw=randread --bs=4k --size=10G --filename=/dev/nvme0n1 \
--rate_iops=10000 \
--percentile_list=50:90:99:99.9:99.99 \
--output-format=normal,latency
Caveats
- Optional engines disabled. Our static build disables
libaio,libpmem,librbd,libcurl+openssl,libibverbs, etc. for portability (see audit #5). If you needlibaio, build fio yourself with./configureomitting the--disable-libaioflag. - Self-contained = no external config files. The static
binary doesn't read
/etc/fio/or~/.fioby default; pass--debug=ioto see where it looks. - Operator-owned filenames. fio does NOT sandbox
--filename=; the operator must vet job files from untrusted sources. See security.