Benchmark and optimize Linux disk I/O performance with fio testing

Beginner 25 min Apr 03, 2026
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Learn how to benchmark disk I/O performance using fio (Flexible I/O tester) to identify storage bottlenecks and optimize your Linux system's disk performance through comprehensive read/write testing and analysis.

Prerequisites

  • Root or sudo access
  • At least 2GB free disk space for testing
  • Basic understanding of Linux file systems

What this solves

Disk I/O performance is critical for application responsiveness and system throughput. The fio (Flexible I/O tester) tool provides comprehensive benchmarking capabilities to measure sequential and random read/write performance, identify storage bottlenecks, and validate storage optimizations. This tutorial shows you how to install fio, run standardized benchmarks, and interpret results to optimize your Linux system's disk performance.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions of all packages.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install fio benchmarking tool

Install fio and related system utilities for disk performance testing. The package includes the main fio binary and documentation.

sudo apt install -y fio iotop hdparm
sudo dnf install -y fio iotop hdparm

Verify fio installation

Check that fio is properly installed and display version information to confirm functionality.

fio --version
which fio

Basic disk performance testing

Create test directory

Create a dedicated directory for benchmarking to isolate test files from system data. Use a location on the disk you want to test.

sudo mkdir -p /tmp/fio-test
cd /tmp/fio-test

Run sequential read performance test

Test sequential read performance with large block sizes to measure maximum throughput. This simulates reading large files or streaming data.

sudo fio --name=sequential-read --ioengine=libaio --rw=read --bs=1M --size=1G --numjobs=1 --time_based --runtime=30 --group_reporting

Run sequential write performance test

Test sequential write performance to measure sustained write throughput. This test creates a 1GB file with 1MB block sizes.

sudo fio --name=sequential-write --ioengine=libaio --rw=write --bs=1M --size=1G --numjobs=1 --time_based --runtime=30 --group_reporting --fsync=1

Run random read performance test

Test random read performance with small block sizes to simulate database or application workloads. This measures IOPS (Input/Output Operations Per Second).

sudo fio --name=random-read --ioengine=libaio --rw=randread --bs=4k --size=1G --numjobs=4 --time_based --runtime=30 --group_reporting --iodepth=32

Run random write performance test

Test random write performance with small blocks to measure worst-case write scenarios. This is critical for database and transactional workloads.

sudo fio --name=random-write --ioengine=libaio --rw=randwrite --bs=4k --size=1G --numjobs=4 --time_based --runtime=30 --group_reporting --iodepth=32 --fsync=1

Advanced mixed workload testing

Create comprehensive benchmark job file

Create a job file that runs multiple tests sequentially to provide a complete performance profile. This saves time and ensures consistent testing parameters.

[global]
ioengine=libaio
direct=1
size=1G
runtime=30
time_based=1
group_reporting=1

[seq-read]
rw=read
bs=1M
numjobs=1
stonewall

[seq-write]
rw=write
bs=1M
numjobs=1
fsync=1
stonewall

[rand-read-4k]
rw=randread
bs=4k
numjobs=4
iodepth=32
stonewall

[rand-write-4k]
rw=randwrite
bs=4k
numjobs=4
iodepth=32
fsync=1
stonewall

[mixed-workload]
rw=randrw
rwmixread=70
bs=4k
numjobs=4
iodepth=16
stonewall

Run comprehensive benchmark suite

Execute the complete benchmark suite and save results to a file for analysis. This provides a standardized performance baseline.

sudo fio /tmp/fio-test/comprehensive-test.fio --output=/tmp/fio-test/results.txt
sudo fio /tmp/fio-test/comprehensive-test.fio --output-format=json --output=/tmp/fio-test/results.json

Test specific device performance

Test a specific block device directly to bypass filesystem overhead. Replace /dev/sdb with your target device. This provides raw storage performance metrics.

Warning: Testing block devices directly will destroy existing data. Only use this on empty or test devices.
sudo fio --name=device-test --ioengine=libaio --direct=1 --filename=/dev/sdb --rw=randread --bs=4k --size=100M --numjobs=1 --time_based --runtime=10

Interpreting benchmark results

Understanding key metrics

Learn how to interpret fio output to identify performance characteristics and bottlenecks. Focus on these critical measurements.

MetricDescriptionGood Values
Bandwidth (BW)Throughput in MB/s or GB/sSequential: 100+ MB/s (HDD), 500+ MB/s (SSD)
IOPSInput/Output Operations Per SecondRandom 4k: 100+ (HDD), 10,000+ (SSD)
LatencyAverage response timeSequential: <10ms, Random: <1ms (SSD)
CPU usageProcessor utilization during I/O<50% for I/O-bound workloads

Compare results with storage type baselines

Use these baseline performance expectations to evaluate your results and identify potential issues.

Storage TypeSequential ReadSequential WriteRandom 4k ReadRandom 4k Write
7200 RPM HDD100-200 MB/s100-180 MB/s100-200 IOPS100-150 IOPS
SATA SSD500-550 MB/s450-520 MB/s10,000-20,000 IOPS8,000-15,000 IOPS
NVMe SSD2,000-7,000 MB/s1,500-6,000 MB/s50,000-500,000 IOPS40,000-300,000 IOPS
Enterprise NVMe3,500-7,000 MB/s3,000-6,500 MB/s100,000-1,000,000 IOPS80,000-800,000 IOPS

Optimizing disk performance based on results

Check current I/O scheduler

Verify and optimize the I/O scheduler for your storage type. Different schedulers work better for different storage technologies.

cat /sys/block/sda/queue/scheduler
echo mq-deadline | sudo tee /sys/block/sda/queue/scheduler

Monitor real-time I/O activity

Use iotop to monitor disk activity during benchmarks and identify processes causing I/O contention. This helps correlate benchmark results with system behavior.

sudo iotop -o
sudo iostat -x 1 5

Clean up test files

Remove benchmark files to free up disk space after testing. Always clean up test data to avoid filling up storage.

sudo rm -rf /tmp/fio-test
sudo sync

Verify your setup

Confirm fio is working properly and you can run basic performance tests.

fio --version
sudo fio --name=quick-test --ioengine=libaio --rw=read --bs=4k --size=10M --numjobs=1 --runtime=5 --time_based
df -h /tmp

Common issues

SymptomCauseFix
Permission denied errorsInsufficient privileges for direct device accessRun fio with sudo or adjust file permissions
Very low performance on all testsSystem under heavy load or failing storageCheck system load with top, test different times
Inconsistent results between runsBackground processes or caching effectsRun sync && echo 3 | sudo tee /proc/sys/vm/drop_caches before tests
fio command not foundPackage not installed or PATH issueReinstall with package manager, check PATH
Tests consume too much disk spaceLarge test file sizes on small filesystemsReduce size parameter or use --time_based option

Next steps

Automated install script

Run this to automate the entire setup

#fio #disk benchmarking #storage performance #io testing #nvme optimization

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer