Skip to main content
RunBook Academy

CephLXXIII · Benchmark InterpretationBenchmark Interpretation

Throughput and saturation

Advanced⏱ ~17 minfioiostatceph

What you'll learn

  • Recognise saturation in benchmark results
  • Identify which resource is saturated
  • Distinguish saturation from other limits
  • Report throughput honestly

Prerequisites

None — start here.

Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18

Not yet marked complete on this device.

Why this matters in production

Saturation is where throughput stops rising and latency starts. Knowing which resource saturated determines what to do about it.

Recognising saturation

for qd in 1 4 16 64 256; do
  fio --name=q$qd --ioengine=rbd --pool=rbd-vms --rbdname=bench \
      --rw=read --bs=4M --iodepth=$qd --runtime=30 --time_based \
      --output-format=json | python3 -c '
import sys,json; d=json.load(sys.stdin)["jobs"][0]["read"]
print("qd %-4s %8.1f MiB/s  %7.2f ms" % ("'"$qd"'", d["bw"]/1024, d["lat_ns"]["mean"]/1e6))'
done
qd 1      412.0 MiB/s     9.71 ms
qd 4     1580.0 MiB/s    10.12 ms
qd 16    2280.0 MiB/s    28.05 ms
qd 64    2310.0 MiB/s   110.60 ms
qd 256   2315.0 MiB/s   441.90 ms

Between qd16 and qd64 throughput stops rising and latency rises in proportion. That is saturation, and qd16 is the useful operating point.

Identifying the saturated resource

# devices
IFACE=bond0
iostat -x 1 5      # on OSD hosts: %util, aqu-sz

# network
sar -n DEV 1 5     # rxkB/s, txkB/s against link capacity
ethtool ${IFACE} | grep Speed

# CPU
mpstat -P ALL 1 5  # on both OSD hosts and the client

# OSD-internal
ceph osd perf | sort -k2 -rn | head -5
SaturatedEvidence
Device%util near 100, aqu-sz high
Networkinterface throughput near link speed
OSD CPUOSD host CPU high, devices not saturated
Client CPUclient CPU high, cluster idle
Client concurrencynothing saturated, throughput flat

The last row is important: flat throughput with nothing saturated means the client is not asking for more.

Distinguishing saturation from other limits

ObservationNot saturation
Throughput flat, everything idleclient-side concurrency limit
Throughput flat, one OSD at 100%one device, not the cluster
Throughput drops as concurrency risescontention or thrashing
Throughput varies run to runinterference
# is it one OSD or all of them?
ceph osd perf | awk 'NR>1 {print $2}' | sort -n | \
  awk '{a[NR]=$1} END {print "median", a[int(NR/2)], "max", a[NR]}'

Reporting honestly

StatementBetter
“The cluster does 2.3 GiB/s”“2.3 GiB/s at 4M sequential read, saturating at qd16”
“Throughput is limited”“Device-bound: OSD %util at 98% during the run”
“Adding OSDs will help”“Device-bound, so adding OSDs adds throughput proportionally”

Naming the saturated resource is what makes the next step obvious rather than a guess.

Quiz

Knowledge check · 4 questions

  1. Q1. Throughput is flat while devices, network, and CPU are all comfortable. What is the constraint?

  2. Q2. Throughput can only plateau at saturation, never decline.

  3. Q3. Determine what to buy after a throughput benchmark.

    A benchmark shows the cluster saturating at 2.3 GiB/s for 4M sequential reads. A proposal is to add more OSDs to increase throughput.

  4. Q4. What does a benchmark that plateaus with everything idle usually indicate about the benchmark itself?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Name the saturated resource alongside any throughput figure — device, network, CPU, or client concurrency — because it determines whether more hardware helps and which hardware. Flat throughput with nothing saturated means the benchmark itself is the limit.

Cross-course references

  • Kubernetes: identifying the saturated resource decides whether to scale out or up
  • Linux: the USE method names utilisation, saturation, and errors for exactly this