iostat Command in Linux: Syntax, Options & Practical Examples (Ubuntu)

Deepak Prasad
Tested on Ubuntu 25.04 (Plucky Puffin)
Package sysstat 12.7.5
sysstat 12.7.5
Applies to Ubuntu, Debian, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux, SUSE, openSUSE, Alpine
Privilege sudo or root
Man page iostat(1)
Scope iostat from the sysstat package reports CPU utilization and per-device disk I/O statistics on Linux. It helps admins spot saturated disks, high iowait, and throughput changes during performance troubleshooting.
Related guides pidstat
Linux commands

iostat — quick reference

Default reports and intervals

When to use Command
CPU and disk stats since boot (or last boot) iostat
Refresh every N seconds iostat N
N samples at M-second intervals iostat M N
Show version (sysstat package) iostat -V

CPU only

When to use Command
CPU utilization report only iostat -c
CPU stats every 2 seconds iostat -c 2
CPU report with timestamp iostat -c -t

Disk devices

When to use Command
Device throughput only (no CPU header) iostat -d
Extended disk stats (await, %util, …) iostat -x
Extended stats every 2 seconds iostat -x 2
One device only iostat -x sda
Hide devices with zero activity iostat -z
Show device-mapper names instead of dm-N iostat -N

Partitions and units

When to use Command
Include partition rows iostat -p
Partitions on one disk iostat -p sda
All partitions including idle iostat -p ALL
Kilobytes per second iostat -k
Megabytes per second iostat -m
Timestamp on each report iostat -t

Structured output

When to use Command
JSON output for scripts iostat -o JSON
Extended disk stats as JSON iostat -x -o JSON
Shorter column widths iostat -s

iostat — command syntax

Synopsis from sysstat 12.7.5 on Ubuntu 25.04:

text
iostat [ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -s ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]

       [ --dec={ 0 | 1 | 2 } ] [ -j { ID | LABEL | PATH | UUID | ... } ]
       [ -o JSON ] [ -p { <device> [,...] | ALL } ] [ <interval> [ <count> ] ]

iostat reads kernel counters; it does not change system state. Historical archives for sar need the sysstat data collector enabled (systemctl enable --now sysstat on Debian/Ubuntu); see the systemctl command for enabling collector units.


iostat — command examples

Essential Default CPU and disk summary

The first screen after boot averages — useful baseline before you add intervals.

Run the command:

bash
iostat | head -15

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.16    0.04   13.02    1.59    0.00   78.18

Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
dm-0            172.93      6243.01       165.76         0.00    1916105      50876          0
sda              93.64      4115.49       135.61         0.00    1273344      41984          0

tps is transfers per second; kB_read/s and kB_wrtn/s are throughput rates.

Essential Live samples every second (interval count)

Pass interval and count to watch a workload for a fixed window.

Run the command:

bash
iostat 1 2 | head -25

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.17    0.04   13.03    1.59    0.00   78.17

Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
dm-0            172.88      6241.18       165.71         0.00    1916105      50876          0
sda              93.64      4115.49       135.61         0.00    1273344      41984          0

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           4.02    0.00    5.03    0.00    0.00   90.95

The second avg-cpu block is the 1-second sample; compare %iowait across intervals during a slow job.

Essential CPU utilization only (-c)

When disk noise is not needed, -c drops the device table.

Run the command:

bash
iostat -c

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.16    0.04   13.02    1.59    0.00   78.18

High %iowait means CPUs were idle waiting for disk I/O — pair with iostat -x on devices.

Common Extended disk metrics (-x)

-x adds latency and utilization columns — the usual starting point for disk bottlenecks.

Run the command:

bash
iostat -x sda

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.17    0.04   13.02    1.59    0.00   78.18

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
sda             78.27   4115.49    29.81  27.58    1.35    52.58    8.44    135.61    11.71  58.11    2.07    16.06    0.00      0.00     0.00   0.00    0.00     0.00    1.10    2.16    0.13   7.53

Watch %util near 100% and await rising — signs the device cannot keep up.

Common Device table without CPU (-d)

Scripts that only care about disk throughput use -d to skip the CPU header.

Run the command:

bash
iostat -d | head -12

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
dm-0            172.92      6242.60       165.75         0.00    1916105      50876          0
sda              93.64      4115.49       135.61         0.00    1273344      41984          0

Add an interval: iostat -d 2 5 for five samples two seconds apart.

Common Throughput in megabytes (-m)

Large sequential workloads are easier to read in MB/s.

Run the command:

bash
iostat -m | head -10

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.17    0.04   13.03    1.59    0.00   78.17

Device             tps    MB_read/s    MB_wrtn/s    MB_dscd/s    MB_read    MB_wrtn    MB_dscd
dm-0            172.89         6.10         0.16         0.00       1871         49          0

-k forces kilobytes if your default display differs.

Common Partition-level stats (-p)

See whether one partition on a disk dominates I/O.

Run the command:

bash
iostat -p | head -12

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.17    0.04   13.03    1.59    0.00   78.17

Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
loop0             0.19         3.54         0.00         0.00       1086          0          0
loop5             1.33        19.05         0.00         0.00       5849          0          0

Use iostat -p sda to limit partition rows to one parent disk.

Advanced LVM names with -N

On LVM systems, dm-0 is opaque. -N maps to the volume name.

Run the command:

bash
iostat -N | head -10

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.15    0.04   12.99    1.58    0.00   78.23

Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
ubuntu--vg-ubuntu--lv   172.30      6220.31       165.16         0.00    1916105      50876          0

Combine with -x for extended metrics on named volumes.

Advanced JSON for monitoring scripts (-o JSON)

Export structured data for dashboards or jq parsing.

Run the command:

bash
iostat -o JSON | head -20

Sample output:

output
{"sysstat": {
	"hosts": [{
			"nodename": "server1",
			"sysname": "Linux",
			"release": "7.0.0-27-generic",
			"machine": "x86_64",
			"number-of-cpus": 2,
			"date": "07/01/2026",
			"statistics": [
				{
					"avg-cpu":  {"user": 7.15, "nice": 0.04, "system": 12.99, "iowait": 1.58, "steal": 0.00, "idle": 78.23},
					"disk": [
						{"disk_device": "dm-0", "tps": 172.29, "kB_read/s": 6220.11, "kB_wrtn/s": 165.16, "kB_dscd/s": 0.00, "kB_read": 1916105, "kB_wrtn": 50876, "kB_dscd": 0},

Pipe to jq to extract one field in automation.

Advanced Timestamped reports (-t)

Correlate disk spikes with wall-clock time in logs.

Run the command:

bash
iostat -t | head -10

Sample output:

output
Linux 7.0.0-27-generic (server1) 	07/01/2026 	_x86_64_	(2 CPU)

07/01/2026 03:35:38 PM
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           7.17    0.04   13.03    1.59    0.00   78.17

Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
dm-0            172.89      6241.59       165.73         0.00    1916105      50876          0

Use iostat -xt 2 during a deployment window.


iostat — when to use / when not

Use iostat when Use something else when
  • You need per-disk throughput, queue depth, await, or %util
  • CPU %iowait is high and you want to confirm which device is busy
  • You are comparing before/after storage changes with interval samples
  • You want JSON export for monitoring
  • You need the process name doing disk I/O → iotop
  • You need memory and run-queue context → vmstat
  • You need historical trends from yesterday → sar
  • You need network or per-CPU history in one tool → dstat or sar suites

iostat vs iotop

iostat iotop
View Block devices Processes / threads
Key metrics tps, await, %util DISK READ/WRITE per task
Privilege User root
Best question "Is the disk saturated?" "Who is writing?"

iostat — interview corner

What is iostat?

iostat is part of sysstat. It prints CPU utilization and disk I/O statistics per device from kernel counters — either since boot or over sampling intervals.

bash
iostat -x 1 3

A strong answer is:

"iostat from sysstat shows CPU iowait and per-device throughput and latency. -x adds await and %util for bottleneck analysis."

What are tps and %util?

tps is I/O transfers per second to the device. %util is the percentage of time the device had at least one request in flight — near 100% means the disk is busy most of the sample.

A strong answer is:

"tps counts I/O operations per second; %util is how busy the device was. High %util with high await means a saturated or slow disk."

What does high %iowait mean?

%iowait is CPU time spent idle while waiting for block I/O. It suggests storage or I/O stack delay, not necessarily high CPU user time.

A strong answer is:

"High iowait means CPUs were waiting on disk. I check iostat -x on devices and iotop for the process driving I/O."

How do you read await?

await is average milliseconds for I/O requests (reads and writes combined on the device). Compare across disks and against SLA expectations for your storage type.

A strong answer is:

"await is average I/O completion time in ms. Rising await under load with high %util indicates the device is struggling to keep up."

iostat vs sar?

iostat is for live snapshots on the terminal. sar reads historical sysstat archives when sysstat collection is enabled.

A strong answer is:

"iostat is real-time; sar is historical from /var/log/sysstat. Both come from sysstat."


Troubleshooting

Symptom Likely cause Fix
command not found sysstat not installed sudo apt install sysstat
sar has no history Collector disabled sudo systemctl enable --now sysstat
Too many loop devices Snap/LVM clutter iostat -z or filter device names
dm-0 not meaningful Device mapper Add -N for LVM names
-h prints stats not help sysstat uses -h for human sizes on some versions Use man iostat for options

Rohan Timalsina

is a technical writer and Linux enthusiast who writes practical guides on Linux commands and system administration. He focuses on simplifying complex topics through clear explanations.

  • Linux
  • HTML5
  • JavaScript
  • Web Design
  • Front-end Web Development