IOSTAT(1)
๐ IOSTAT(1) โ like, the Linux User's Manual, but make it cute
okay bestie, buckle up โ this is iostat, and she's from the Linux User's Manual, section 1. yes, that manual. ๐
โจ NAME โจ
iostat โ reports Central Processing Unit (CPU) statistics and input/output statistics for devices and partitions. both. at once. she multi-tasks. ๐
โจ SYNOPSIS โจ
iostat [ -c ] [ -d ] [ -h ] [ -k | -m | -G ] [ -N ] [ -s ] [ -t ] [ -U ]
[ -V ] [ -x ] [ -y ] [ -z ] [ --compact ] [ --dec={ 0 | 1 | 2 } ] [ { -f
| +f } directory ] [ -j { ID | LABEL | PATH | UUID | ... } ] [ -o JSON ]
[ [ -H ] -g group_name ] [ --human ] [ --pretty ] [ -p [ device[,...] |
ALL ] ] [ device [...] | ALL ] [ interval [ count ] ]
like, yes, that's a lot of brackets. she's flexible. she contains multitudes. ๐ฆ
โจ DESCRIPTION โจ
so the whole point of iostat, fr fr, is monitoring your system's input/output device loading โ she does this by watching how long your devices are actually active compared to their average transfer rates. and then she generates reports ๐ that you can use to change your system configuration so the input/output load is better balanced between your physical disks. she's literally a load-balancing therapist for your disks. and she ate. ๐ฅ
okay so about the reports โ this part matters, don't @ me:
- The first report covers the time since the system was booted. UNLESS you used the
-yoption, in which case this first report is omitted. (not me skipping the intro, but make it-y๐) - Each subsequent report covers the time since the previous report.
- All statistics get reported every single time
iostatruns. every. time. ๐
and what does a report actually look like, you ask? ๐ง
- a CPU header row, followed by
- a row of CPU statistics. and on multiprocessor systems, those CPU stats are calculated system-wide as averages among all processors โ so she's giving you the whole squad's average, not one quirky core.
- then a device header row shows up, followed by a line of statistics for each device that is configured. one line per device. slay.
now the timing params, bestie, pay attention:
intervalโ the amount of time in seconds between each report. that's it. that's the vibe check on timing. โฑ๏ธcountโ can be specified in conjunction withinterval. if you do, the value ofcountdetermines the number of reports generated, atintervalseconds apart. so like, how many, and how far apart. iconic.- If you specify
intervalwithoutcount? Theiostatcommand generates reports continuously. forever. she will not stop. she has no off switch. ๐ญ๐
lowkey a warning: interval without count = infinite report mode. know what you're getting into before you type it, bestie ๐ซถ
okay that's the setup, next parts have all the options and she has so many options ๐
โจ REPORTS โจ
okay so iostat lowkey just makes two kinds of reports and that's it โ the CPU Utilization report and the Device Utilization report. Two icons, two vibes, let's go ๐
๐ CPU Utilization Report ๐
this one's the first report that pops out when you run iostat. heads up for the multiprocessor girlies: on multiprocessor systems the CPU values are global averages among all processors, so you're seeing the whole squad's average, not each core's individual moment. it's giving group project energy ๐ซถ
the report has this format:
%userโ the percentage of CPU utilization that happened while executing at the user level (application). that's your apps doing their thing โจ%niceโ the percentage of CPU utilization that happened while executing at the user level with nice priority.%systemโ the percentage of CPU utilization that happened while executing at the system level (kernel). kernel's turn to shine ๐%iowaitโ the percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request. so: bored but waiting on the disk ๐ญ%stealโ the percentage of time spent in involuntary wait by the virtual CPU or CPUs while the hypervisor was servicing another virtual processor. you're literally being ghosted by your own hypervisor ๐%idleโ the percentage of time that the CPU or CPUs were idle and the system did not have an outstanding disk I/O request. fully chillin', no disk drama ๐ฆ
๐ธ Device Utilization Report ๐ธ
the second report, bestie. this one gives you stats on a per physical device or partition basis. block devices and partitions you want stats for can be entered right there on the command line ๐
- if you enter no device nor partition, then stats get displayed for every device used by the system โ providing that the kernel maintains statistics for it. iykyk, kernel's choice ๐
- if you give the
ALLkeyword on the command line, then stats are displayed for every device defined by the system, including the ones that have never been used. the whole roster, no exclusions ๐
transfer rates are shown in 1024-byte blocks by default, unless the environment variable POSIXLY_CORRECT is set โ in which case 512-byte blocks are used. ok periodt, know the difference ๐
the report may show the following fields, depending on the flags used (e.g. -x, -s and -k, -m or -G) โ so like, not everything shows up every time, it's a vibe check on your flags:
Device:โ this column gives the device (or partition) name as listed in the/devdirectory. literally just the name, no cap.tpsโ the number of transfers per second that were issued to the device. a transfer is an I/O request to the device. multiple logical requests can be combined into a single I/O request to the device. a transfer is of indeterminate size. so like, don't assume how big it is, because nobody knows ๐Blk_read/s(kB_read/s,MB_read/s,GB_read/s) โ the amount of data read from the device expressed in a number of blocks (kibibytes, mebibytes, gibibytes) per second. blocks are equivalent to sectors and therefore have a size of 512 bytes. key detail, don't forget it โญBlk_wrtn/s(kB_wrtn/s,MB_wrtn/s,GB_wrtn/s) โ the amount of data written to the device expressed in a number of blocks (kibibytes, mebibytes, gibibytes) per second.Blk_dscd/s(kB_dscd/s,MB_dscd/s,GB_dscd/s) โ the amount of data discarded for the device expressed in a number of blocks (kibibytes, mebibytes, gibibytes) per second. bye bestie ๐๏ธBlk_w+d/s(kB_w+d/s,MB_w+d/s,GB_w+d/s) โ the amount of data written to or discarded for the device expressed in a number of blocks (kibibytes, mebibytes, gibibytes) per second.Blk_read(kB_read,MB_read,GB_read) โ the total number of blocks (kibibytes, mebibytes, gibibytes) read.Blk_wrtn(kB_wrtn,MB_wrtn,GB_wrtn) โ the total number of blocks (kibibytes, mebibytes, gibibytes) written.Blk_dscd(kB_dscd,MB_dscd,GB_dscd) โ the total number of blocks (kibibytes, mebibytes, gibibytes) discarded.Blk_w+d(kB_w+d,MB_w+d,GB_w+d) โ the total number of blocks (kibibytes, mebibytes, gibibytes) written or discarded.r/sโ the number (after merges) of read requests completed per second for the device.w/sโ the number (after merges) of write requests completed per second for the device.d/sโ the number (after merges) of discard requests completed per second for the device.f/sโ the number (after merges) of flush requests completed per second for the device. this counts flush requests executed by disks. flush requests are not tracked for partitions. before being merged, flush operations are counted as writes. so many little caveats, but we love her ๐ซถsec/s(kB/s,MB/s,GB/s) โ the number of sectors (kibibytes, mebibytes, gibibytes) read from, written to or discarded for the device per second.rsec/s(rkB/s,rMB/s,rGB/s) โ the number of sectors (kibibytes, mebibytes, gibibytes) read from the device per second.wsec/s(wkB/s,wMB/s,wGB/s) โ the number of sectors (kibibytes, mebibytes, gibibytes) written to the device per second.dsec/s(dkB/s,dMB/s,dGB/s) โ the number of sectors (kibibytes, mebibytes, gibibytes) discarded for the device per second.rqm/sโ the number of I/O requests merged per second that were queued to the device.rrqm/sโ the number of read requests merged per second that were queued to the device.wrqm/sโ the number of write requests merged per second that were queued to the device.drqm/sโ the number of discard requests merged per second that were queued to the device.%rrqmโ the percentage of read requests merged together before being sent to the device.%wrqmโ the percentage of write requests merged together before being sent to the device.%drqmโ the percentage of discard requests merged together before being sent to the device.areq-szโ the average size (in kibibytes) of the I/O requests that were issued to the device.
๐ Note: in previous versions, this field was known as avgrq-sz and was expressed in sectors. glow-up, honestly.
rareq-szโ the average size (in kibibytes) of the read requests that were issued to the device.wareq-szโ the average size (in kibibytes) of the write requests that were issued to the device.dareq-szโ the average size (in kibibytes) of the discard requests that were issued to the device.awaitโ the average time (in milliseconds) for I/O requests issued to the device to be served. this includes the time spent by the requests in queue and the time spent servicing them. both parts, bestie ๐r_awaitโ the average time (in milliseconds) for read requests issued to the device to be served. includes the time spent by the requests in queue and the time spent servicing them.w_awaitโ the average time (in milliseconds) for write requests issued to the device to be served. includes the time spent by the requests in queue and the time spent servicing them.d_awaitโ the average time (in milliseconds) for discard requests issued to the device to be served. includes the time spent by the requests in queue and the time spent servicing them.f_awaitโ the average time (in milliseconds) for flush requests issued to the device to be served. the block layer combines flush requests and executes at most one at a time. thus flush operations could be twice as long: wait for current flush request, then execute it, then wait for the next one. so yeah, queue theory but make it tragic ๐ญaqu-szโ the average queue length of the requests that were issued to the device.
๐ Note: in previous versions, this field was known as avgqu-sz. another rebrand, we stan a rebrand ๐
%utilโ percentage of elapsed time during which I/O requests were issued to the device (bandwidth utilization for the device). device saturation occurs when this value is close to 100% for devices serving requests serially. but for devices serving requests in parallel, such as RAID arrays and modern SSDs, this number does not reflect their performance limits. big warning, don't come for her when your NVMe looks weird, she literally told you ๐ฅ
โจ OPTIONS โจ
Okay bestie, here's the menu. Every flag, all of them, no skipping ๐
-cโ shows the CPU utilization report.--compactโ tells iostat not to break the Device Utilization Report into sub-reports, so all the metrics get squished onto a single line. one line. that's the whole vibe.-dโ shows the device utilization report.--dec={ 0 | 1 | 2 }โ picks how many decimal places you want (0to2, and the default is2).-f directory,+f directoryโ points iostat at a different directory to read device stats from. The difference is lowkey important:-fsays only use the files in that alternative directory.+fsays use both the standard kernel files and the files in the alternative directory to read device statistics.
directory is a directory holding stats for devices managed in userspace. It may contain:
- a
"diskstats"file whose format matches the one in"/proc", - stats for individual devices in files whose format matches those in
"/sys".
Specifically, these files inside directory may get used by iostat:
directory/block/device/stat
directory/block/device/partition/stat
partition files must have an entry in directory/dev/block/ directory, like:
directory/dev/block/major:minor --> ../../block/device/partition
-Gโ stats in gibibytes per second ๐ซถ-g group_name { device [...] | ALL }โ shows stats for a whole group of devices. iostat reports stats for each individual device in the list, then a line of global stats for the group, displayed asgroup_nameand made up of all the devices in the list. TheALLkeyword means every block device the system defines gets included in the group.-Hโ has to be used with-g, and it means only the global stats for the group get displayed โ no per-device stats for the individual devices in the group ๐-hโ literally the same as saying--human --pretty.--humanโ prints sizes in human readable format (like1.0k,1.2M, etc.). The units shown with this option override any other default units (like kibibytes, sectors...) that come attached to the metrics.-j { ID | LABEL | PATH | UUID | ... } [ device [...] | ALL ]โ shows persistent device names. Keywords likeID,LABEL, etc. say what type of persistent name you want. These keywords aren't a limited set โ the only prerequisite is that the directory with the required persistent names exists in/dev/disk. Optionally you can list multiple devices in the chosen persistent name type. And because persistent device names are usually long,--prettyis implicitly set with this option.-kโ stats in kibibytes per second.-mโ stats in mebibytes per second.-Nโ shows the registered device mapper names for any device mapper devices. Useful for viewing LVM2 statistics ๐-o JSONโ spits the stats out in JSON (JavaScript Object Notation) format. Heads up: JSON output field order is undefined, and new fields may be added in the future. so don't get too attached to the ordering fr fr.-p [ { device[,...] | ALL } ]โ shows stats for block devices and all their partitions that the system is using. If you type a device name on the command line, then stats for it and all its partitions get displayed. And last, theALLkeyword means stats have to be displayed for all the block devices and partitions the system defines โ including the ones that have never been used ๐. If-jis defined before this option, devices entered on the command line can be specified with the chosen persistent name type.--prettyโ makes the Device Utilization Report easier for a human to read. The device name gets printed on the right side. The report may also be broken into sub-reports if there are lots of metrics to display (use--compactto prevent that).-sโ shows a short (narrow) version of the report that should fit on screens 80 characters wide ๐ธ-tโ prints the time for each report displayed. The timestamp format may depend on the value of theS_TIME_FORMATenvironment variable (peep below) and on whether-Uwas used.-Uโ shows the timestamp (UTC โ Coordinated Universal Time) in seconds from the epoch.-Vโ prints the version number then exits.-xโ shows extended statistics.-yโ omits the first report (the one with stats since system boot) if you're displaying multiple records at a given interval.-zโ tells iostat to omit output for any devices that had no activity during the sample period.
๐ ENVIRONMENT ๐
iostat takes these environment variables into account, bestie:
POSIXLY_CORRECT
When this variable is set, transfer rates get shown in 512-byte blocks instead of the default 1024-byte blocks.
S_COLORS
By default, statistics are displayed in color when the output is connected to a terminal. Use this variable to change the settings. Possible values are never, always or auto (the last one is equivalent to the default settings).
๐ Please note that the color being used (red, yellow, or whatever) to display a value is not indicative of any kind of issue just because of the color. It only indicates different ranges of values. no cap, don't panic.
S_COLORS_SGR
Specifies the colors and other attributes used to display statistics on the terminal. Its value is a colon-separated list of capabilities that defaults to I=32;22:N=34;1:W=35;1:X=31;1:Z=34;22. Supported capabilities:
I=โ SGR (Select Graphic Rendition) substring for device names.N=โ SGR substring for non-zero statistics values.W=(orM=) โ SGR substring for percentage values in the range from 75% to 90% (or in the range 10% to 25% depending on the metric's meaning).X=(orH=) โ SGR substring for percentage values greater than or equal to 90% (or lower than or equal to 10% depending on the metric's meaning).Z=โ SGR substring for zero values.
S_TIME_FORMAT
If this variable exists and its value is ISO then the current locale gets ignored when printing the date in the report header. The iostat command will use the ISO 8601 format (YYYY-MM-DD) instead. The timestamp displayed with option -t will also be compliant with ISO 8601 format โจ
๐ EXAMPLES ๐
iostatโ display a single history since boot report for all CPU and Devices.iostat -d 2โ display a continuous device report at two second intervals.iostat -d 2 6โ display six reports at two second intervals for all devices.iostat -x sda sdb 2 6โ display six reports of extended statistics at two second intervals for devicessdaandsdb.iostat -p sda 2 6โ display six reports at two second intervals for devicesdaand all its partitions (sda1, etc.)
๐ BUGS ๐
The /proc filesystem must be mounted for iostat to work. non-negotiable.
Kernels older than 2.6.x are no longer supported. sorry bestie, ancient kernel rights revoked.
And this one's iconic: although iostat displays units corresponding to kilobytes (kB), megabytes (MB), gigabytes (GB)..., it actually uses kibibytes (kiB), mebibytes (MiB), gibibytes (GiB)... A kibibyte is equal to 1024 bytes, a mebibyte is equal to 1024 kibibytes, and a gibibyte is equal to 1024 mebibytes. it's giving "technically the label is lying" but now you know ๐
๐ฆ FILES ๐ฆ
/proc/statโ contains system statistics./proc/uptimeโ contains system uptime./proc/diskstatsโ contains disks statistics./sysโ contains statistics for block devices./proc/self/mountstatsโ contains statistics for network filesystems./dev/diskโ contains persistent device names.
๐ AUTHOR ๐
Sebastien Godard (sysstat <at> orange.fr)
๐ธ SEE ALSO ๐ธ
sar(1), pidstat(1), mpstat(1), vmstat(8), tapestat(1), nfsiostat(1), cifsiostat(1)
Okay that's the whole page, you're officially an iostat girlie now ๐ง๐ This one's from the Linux fam, AUGUST 2026 edition, filed under IOSTAT(1) โ go forth and -x responsibly, bestie ๐
โจ๐
๐ฆ where this page comes from
- arch rolling: sysstat 12.8.0-1 ยท GPL-2.0-only
- nixpkgs unstable: sysstat 12.8.0
- (C) 1998-2025 Sebastien Godard (sysstat <at> orange.fr)
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms