Skip to main content
RunBook Academy

CephLXXVII · AlertingAlerting

The slow ops alert and its escalation

Advanced⏱ ~17 minceph

What you'll learn

  • Set severity for slow ops based on context
  • Sequence the investigation efficiently
  • Decide when slow ops warrant escalation
  • Distinguish slow ops from blocked ops in the response

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

Slow ops during a recovery on a busy cluster is expected. The same alert with no recovery running and an idle cluster is a fault. The alert cannot distinguish them; the response must.

Context-dependent severity

- alert: CephSlowOpsWithRecovery
  expr: |
    ceph_health_detail{name="SLOW_OPS"} == 1
      and on() (ceph_pg_recovering + ceph_pg_backfilling) > 0
  for: 30m
  labels: { severity: ticket }
  annotations:
    summary: "Slow ops during recovery — expected, but check the duration"

- alert: CephSlowOpsNoRecovery
  expr: |
    ceph_health_detail{name="SLOW_OPS"} == 1
      and on() (ceph_pg_recovering + ceph_pg_backfilling) == 0
  for: 10m
  labels: { severity: page }
  annotations:
    summary: "Slow ops with no recovery running — a fault is likely"

Two rules from one condition, distinguished by context, with different severities and durations.

The investigation sequence

# 1. which daemons, and how long?
ceph health detail | grep -A5 SLOW_OPS

# 2. what stage are the operations stuck at?
for osd in $(ceph health detail | grep -oE 'osd\.[0-9]+' | sort -u | head -3); do
  echo "== $osd"
  ceph daemon "$osd" dump_ops_in_flight 2>/dev/null | python3 -c '
import sys,json
d=json.load(sys.stdin)
for op in d.get("ops",[])[:3]:
    print("  ", op.get("type_data",{}).get("flag_point"))' 2>/dev/null
done

# 3. is another OSD implicated?
ceph health detail | grep -oE 'waiting for subops from [0-9,]+'

# 4. the layer below
ceph osd perf | sort -k2 -rn | head -5

Four steps, each narrowing. The flag_point in step 2 is the highest-value output.

When to escalate

ConditionEscalate?
Slow ops during a known recovery, count fallingno
Slow ops with no recoveryyes
Oldest blocked operation growing without boundyes
Slow ops plus OSD_DOWNyes
Slow ops on a single OSD, others fineinvestigate first
Slow ops cluster-wideyes
Slow ops plus client-reported impactyes
# is the oldest operation age growing?
ceph health detail | grep -o 'blocked for [0-9]*'
sleep 120
ceph health detail | grep -o 'blocked for [0-9]*'

An age growing by the elapsed time with no operations completing means blocked rather than slow, which is a different and more serious condition.

Slow versus blocked in the response

SlowBlocked
Operations completeeventuallynot until a condition changes
Causecontention, a slow devicea state forbidding progress
First checkceph osd perf, device metricsPG states, quotas, flags, quorum
Escalationif persistentimmediately

Quiz

Knowledge check · 4 questions

  1. Q1. How do you distinguish blocked operations from slow ones using the health output?

  2. Q2. A single SLOW_OPS alert rule with one severity is adequate.

  3. Q3. Respond to a slow ops alert.

    A slow ops alert fires. Two OSDs are named, the oldest operation is blocked for 92 seconds, and no recovery is running.

  4. Q4. What context should be added to a slow ops alert expression, and why?

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

Production discipline

Write two SLOW_OPS rules distinguished by whether recovery is running — one condition with opposite meanings cannot share a severity. Sample the oldest blocked age twice before investigating: growth matching elapsed time means blocked, which is a different and more urgent condition.

Cross-course references

  • Kubernetes: the same alert during a rollout versus at steady state warrants different urgency
  • Linux: distinguishing a slow process from a blocked one changes the entire investigation