Linux uses spare RAM as disk cache, so low "free" memory is healthy; what counts is available, free memory plus cache the kernel can drop. vmstat samples CPU, memory, swap and block I/O each second; iostat (package sysstat 12.7.7 3,369 , github.com/sysstat/sysstat (https://github.com/sysstat/sysstat 3,369 )) splits I/O per device. Here both watch a 6 GB direct write that bypasses the cache:
free -h
dd if=/dev/zero of=/var/tmp/ch01-08/big.bin bs=1M count=6000 oflag=direct status=none &
vmstat 1 2
iostat -dxsyz sde 1 1 # extended, short, skip the since-boot report, hide idle devices
wait; rm /var/tmp/ch01-08/big.bintotal used free shared buff/cache available Mem: 62Gi 1.7Gi 60Gi 12Mi 695Mi 60Gi Swap: 16Gi 0B 16Gi procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu------- r b swpd free buff cache si so bi bo in cs us sy id wa st gu 2 0 0 63732992 9200 703416 0 0 1554 13687 1857 0 0 0 99 0 0 0 0 1 0 63731976 9288 703472 0 0 84 2598912 4702 6223 0 1 97 2 0 0 ... Device tps kB/s rqm/s await areq-sz aqu-sz %util sde 2641.00 2683984.00 0.00 0.28 1016.28 0.73 71.60
Skip the first vmstat line (a since-boot average). During the write, bo (KiB/s out) hit 2.6 million, b shows one process blocked on I/O and wa rose to 2%. A 0.28 ms await is fast; tens of milliseconds with high wa mean storage is the bottleneck, often slow queries (MySQL). Steady swapping (si, so above zero) is an emergency: cut the worker count before adding swap.