Skip to main content
RunBook Academy

CephLXXIX · Slow OpsSlow Ops

Slow ops originating at an OSD

Advanced⏱ ~18 mincephiostat

What you'll learn

  • Confirm the OSD is the source of the delay
  • Identify which OSD-internal cause applies
  • Gather the evidence for each
  • Apply the appropriate remedy

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

An OSD holding operations may be waiting on something else or may be the delay itself. The flag point distinguishes them and determines everything that follows.

Confirming the OSD is the source

ceph daemon osd.12 dump_ops_in_flight | python3 -c '
import sys,json
d = json.load(sys.stdin)
from collections import Counter
c = Counter(op.get("type_data",{}).get("flag_point") for op in d.get("ops",[]))
for k, v in c.most_common(): print("%4d  %s" % (v, k))'
Flag pointSource
waiting for subops from [N]another OSD — investigate N
waiting for degraded objectrecovery, not this OSD
waiting for rw lockscontention on the object
queued for pgthis OSD’s queue
reached pg / startedthis OSD’s processing
commit sent; apply or cleanupthis OSD’s local write

Only the last three implicate this OSD.

The OSD-internal causes

ceph daemon osd.12 perf dump | python3 -c '
import sys,json
d = json.load(sys.stdin)
o, b = d["osd"], d.get("bluestore", {})
for name, src in (("op_latency", o), ("op_w_process_latency", o),
                  ("kv_sync_lat", b), ("kv_commit_lat", b),
                  ("state_kv_queued_lat", b), ("submit_lat", b)):
    v = src.get(name, {})
    if v.get("avgcount"):
        print("%-24s %8.2f ms" % (name, v["sum"]/v["avgcount"]*1000))'
CauseEvidence
The data device is slowiostat await high, op_w_process_latency high
The DB device is slowkv_sync_lat and kv_commit_lat high
RocksDB compactionperiodic kv_* spikes, log entries
Memory pressureosd_memory_target exceeded, host swapping
CPU starvationhost load high, queued for pg dominant
Too many PGs on this OSDceph osd df shows a high PG count
Scrub in progressceph pg ls-by-osd shows scrubbing
ceph osd df | awk -v o=12 'NR==1 || $1==o'
ceph pg ls-by-osd 12 | grep -c scrub

Gathering the evidence

# host side, on the OSD's host
ceph osd find 12
iostat -x 1 5
vmstat 1 5
free -g

# the fsid names the systemd unit
FSID=$(ceph fsid)
journalctl -u "ceph-$FSID@osd.12" --since '30 min ago' | grep -iE 'slow|stall|compact'

The daemon log is frequently decisive: BlueStore logs compaction events and RocksDB stalls explicitly.

The remedies

CauseRemedy
Slow data devicereplace
Slow DB devicereplace; check DB device sizing
Compaction stallsfaster DB device, fewer OSDs per DB device
Memory pressurelower osd_memory_target or add RAM
CPU starvationfewer OSDs per host, or more CPU
High PG countrun the balancer
Scrubreschedule; not a fault

Quiz

Knowledge check · 4 questions

  1. Q1. An OSD's operations are mostly at flag point `waiting for subops from [31]`. What does this mean?

  2. Q2. An OSD can report slow ops purely because CRUSH gave it more PGs than its peers, with nothing wrong with its hardware.

  3. Q3. Isolate a DB device problem.

    One OSD reports slow ops. Its data device shows normal await in iostat. The BlueStore perf dump shows kv_sync_lat at 180 ms while op_w_process_latency is proportionally elevated.

  4. Q4. Which three flag points implicate the reporting OSD itself?

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

Production discipline

Read the flag point distribution before investigating an OSD — only queued for pg, started, and the local commit stages implicate it, and waiting for subops names a different OSD entirely. Check ceph osd df for PG count before concluding hardware; an over-assigned OSD produces identical symptoms.

Cross-course references

  • Kubernetes: a pod slow because it waits on a dependency versus one slow itself
  • Linux: distinguishing local I/O latency from remote wait in a distributed system