CephLXVII · Performance MethodologyPerformance Methodology
Isolating the slow layer
What you'll learn
- Run an isolating test for each layer
- Interpret each result against the expected range
- Work from the bottom layer upward
- Recognise when a layer is exonerated
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
Why this matters in production
Each layer’s test must exclude the layers above it, or the result is a combined measurement that proves nothing about any single layer.
Device layer
# on the OSD host, against the raw device — NOT the OSD's filesystem
fio --name=devtest --filename=/dev/sdX --direct=1 --rw=randread \
--bs=4k --iodepth=1 --runtime=30 --time_based --readonly
--readonly and a read workload are essential: writing to a device an OSD
is using destroys data.
| Device | Expected 4k random read, qd1 |
|---|---|
| HDD 7200 rpm | 5–15 ms |
| SATA SSD | 0.1–0.5 ms |
| NVMe | 50–300 µs |
Above the range for its class, the device is the problem and nothing above it needs investigating yet.
Network layer
HOST=stor-04
iperf3 -s # on one host
iperf3 -c ${HOST} -t 30 -P 4 # on the other
ping -c 1000 -i 0.01 ${HOST} | tail -3
ping -M do -s 8972 -c 5 ${HOST} # MTU verification for a 9000 MTU
# loss and errors on the interface
IFACE=bond0
ip -s link show ${IFACE}
ethtool -S ${IFACE} | grep -iE 'drop|err|discard'
Any non-zero loss on a cluster network is significant; Ceph’s behaviour degrades sharply with even fractional-percent loss.
OSD layer
ceph osd perf | sort -k2 -n | tail -10
ceph daemon osd.12 perf dump | python3 -c '
import sys,json; d=json.load(sys.stdin)["osd"]
for k in ("op_latency","op_w_latency","op_r_latency","subop_latency"):
v=d.get(k,{})
if v.get("avgcount"): print(k, round(v["sum"]/v["avgcount"]*1000,2), "ms")'
Comparing the OSD’s reported latency against the device’s measured latency is the key step: a large gap is queueing or processing inside the OSD.
RADOS layer
rados bench -p bench 30 write --no-cleanup
rados bench -p bench 30 rand
rados -p bench cleanup
This includes the network and the OSDs but excludes RBD and the client library.
Client layer
rbd perf image iostat --pool rbd-vms
fio --name=clienttest --ioengine=rbd --pool=rbd-vms --rbdname=bench \
--rw=randread --bs=4k --iodepth=1 --runtime=30 --time_based
Working bottom-up
device OK → network OK → OSD OK → RADOS OK → client is the problem
device OK → network OK → OSD slow → the OSD's queue or threading
device OK → network lossy → the network
device slow → the device
Stopping at the first layer that fails avoids the common error of tuning the OSD when the device is at 40 ms.
Quiz
Knowledge check · 4 questions
Q1. The OSD reports 30 ms operation latency and the raw device measures 2 ms service time. What does this indicate?
Q2. A `fio` write test against an in-service OSD device is a valid way to measure its write latency.
Q3. Isolate a latency problem across layers.
Clients report 45 ms write latency against a pool whose baseline is 8 ms. The cluster is HEALTH_OK. No recent changes are known.
Q4. What are the expected 4k random read latencies at queue depth 1 for HDD, SATA SSD, and NVMe?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Test each layer in a way that excludes the layers above it and work
bottom-up, stopping at the first failure — a combined measurement proves
nothing about any single layer. Compare ceph osd perf against raw device
latency early; the gap decides whether to tune the OSD or replace the
device.
Cross-course references
- Kubernetes: isolating node, network, and container layers uses the same exclusion principle
- Linux: measuring the block layer separately from the filesystem is the same technique