fio: Usage, Options & Common CI Errors
fio measures storage throughput, IOPS, and latency under custom workloads.
fio is the definitive disk I/O benchmark. Its sharp edges in CI are the test file size versus available disk, and direct I/O not being supported on overlay/tmpfs filesystems.
What it does
fio runs flexible I/O workloads defined by read/write mix, block size, queue depth, and engine, then reports IOPS, bandwidth, and latency percentiles. Workloads can be given as flags or a job file.
Common usage
fio --name=randread --rw=randread --bs=4k --size=1G --runtime=30s --time_based
fio --name=write --rw=write --bs=1M --size=512M --direct=1
fio --name=mix --rw=randrw --rwmixread=70 --iodepth=16 --numjobs=4 --size=1G
fio jobfile.fio
fio --name=t --rw=read --size=256M --ioengine=libaio --direct=1 --output-format=jsonOptions
| Flag | What it does |
|---|---|
| --rw <mode> | read | write | randread | randwrite | randrw |
| --bs <size> | Block size (e.g. 4k, 1M) |
| --iodepth <N> | Queue depth for async engines |
| --size <sz> / --runtime <t> | Per-job data size / time limit |
| --direct=1 | Bypass the page cache (O_DIRECT) |
| --ioengine <eng> | sync, libaio, io_uring, … |
Common errors in CI
"fio: io_u error ... No space left on device" / "Disk full" means --size exceeds free space on the runner - shrink it. "file:engines/libaio.c ... Operation not supported" or "fio: first direct IO errored ... O_DIRECT" means the filesystem (overlayfs, tmpfs in many container runners) does not support libaio or --direct=1 - drop --direct or use --ioengine=sync. Leaving the test file behind eats disk on shared runners; clean it up. Numbers vary wildly between a real EBS volume and an overlay FS - pin the target path.