Monitoring Disk I/O Performance on Linux

Disk subsystems are often the slowest component in a computer system and a common source of performance bottlenecks. This is due to the physical distance from the CPU and the mechanical operations—such as disk rotation and head movement—required for data access. The performance gap betwean memory and disk is orders of magnitude, akin to comparing one minute to an entire day.

Page-Based I/O

Linux manages I/O between memory and disk in fixed-size units called pages. On most systems, a page is 4KB. You can verify this with:

/usr/bin/time -v date | grep "Page size"

Page Faults

Virtual memory allows programs to use more address space than physically available RAM by swapping inactive pages to disk. When a process accesses a page not currently in RAM, a page fault occurs. There are two types:

  • Minor page faults: The required page is already in memory (e.g., in buffer or page cache), so no disk I/O is needed.
  • Major page faults: The page must be fetched from disk, triggering actual I/O.

The kernel prioritizes reading from caches before falling back to disk. Increasing available memory improves cache hit rates, reducing major faults. To observe faults during program startup:

/usr/bin/time -v date | grep -E "(Major|Minor).*fault"

Buffer and Page Cache

Linux uses unused RAM as a file cache (Cached) and block buffer (Buffers) to accelerate disk reads. This explains why MemFree often appears low even on idle systems—it’s being used effectively as cache. Example from /proc/meminfo:

MemTotal:      8182776 kB
MemFree:       3053808 kB
Buffers:        342704 kB
Cached:        3972748 kB

Here, ~4GB is used for caching, significantly speeding up repeated file accesses.

Page Types in Memory

Pages fall into three categories:

  • Read-only pages: Loaded from static files (binaries, libraries). Discarded under memory pressure and reloaded via major faults when needed.
  • Dirty pages: Modified in memory (e.g., edited files). Written back to disk by pdflush or writeback threads when flushed or under memory pressure.
  • Anonymous pages: Process-private data not tied to any file (e.g., heap allocations). Swapped to swap space when memory is scarce.

IOPS and Access Patterns

Disk performance is constrained by IOPS (Input/Output Operations Per Second). Random access is especially slow—on older hardware, a random read might take ~8ms, yielding only ~125 IOPS.

Sequential vs. Random I/O

  • Sequential I/O: Large, contiguous transfers (e.g., video streaming, database scans). Performance is measured in throughput (KB per I/O). Use iostat -kx 1 and compute rkB/s ÷ r/s or wkB/s ÷ w/s. High values (e.g., >400 KB/I/O) indicate sequential behavior.
Device:  r/s    w/s    rkB/s    wkB/s   avgrq-sz
sdb     29.00  99.00   4228.00  45060.00   770.12  # ~455 KB/write
  • Random I/O: Small, scattered requests (e.g., web servers, mail systems). Throughput per I/O is low (<10 KB), so total IOPS matters more.
Device:  r/s    w/s    rkB/s    wkB/s   avgrq-sz
sdb      0.00  57.00     0.00    436.00    15.30  # ~7.6 KB/write

Swap Activity

When physical memory is exhausted, Linux moves anonymous pages to swap (a partition or file). Heavy swapping severely degrades perfromance, especially if swap resides on the same disk as active data.

Monitor swap usage via:

# Total and free swap
grep -E "Swap(Total|Free)" /proc/meminfo

# Real-time swap-in (si) and swap-out (so)
vmstat 1

High si/so values in vmstat indicate thrashing—a critical performance issue.

Tags: Linux Performance disk-io iostat vmstat

Posted on Thu, 22 Oct 2026 16:04:53 +0000 by morleypotter