Skip to main content
RunBook Academy

CephLXI · ScrubbingScrubbing

Tuning scrub deliberately

Advanced⏱ ~18 minceph

What you'll learn

  • Identify the settings that shape scrub behaviour
  • Understand how they interact
  • Configure scrub for a given cluster type
  • Verify the configuration is achieving its intent

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

Scrub configuration is a set of interacting settings, and the interactions are where the mistakes live. A defensible configuration comes from choosing an intent and then setting the values that serve it.

The settings

ceph config get osd osd_max_scrubs
ceph config get osd osd_scrub_load_threshold
ceph config get osd osd_scrub_begin_hour
ceph config get osd osd_scrub_end_hour
ceph config get osd osd_scrub_sleep
ceph config get osd osd_deep_scrub_interval
ceph config get osd osd_scrub_max_interval
ceph config get osd osd_deep_scrub_stride
SettingShapes
osd_max_scrubsconcurrency per OSD
osd_scrub_load_thresholdwhether a scrub starts under load
osd_scrub_begin_hour / _end_hourthe permitted window
osd_scrub_sleepdelay between scrub chunks
osd_deep_scrub_intervalhow often bytes are verified
osd_deep_scrub_stridebytes read per deep scrub chunk

Per-pool control

ceph osd pool set backups noscrub false
ceph osd pool set backups nodeep-scrub false
ceph osd pool set scratch nodeep-scrub true
ceph osd pool get rbd-vms scrub_min_interval

Per-pool settings are the sharpest tool: they let a scratch pool be scrubbed rarely while an archive pool is scrubbed on schedule, which a cluster-wide setting cannot express.

Configurations by cluster type

HDD, latency-sensitive

ceph config set osd osd_max_scrubs 1
ceph config set osd osd_scrub_begin_hour 22
ceph config set osd osd_scrub_end_hour 6
ceph config set osd osd_scrub_load_threshold 2.0
ceph config set osd osd_deep_scrub_interval 1209600
ceph config set osd osd_scrub_sleep 0.1

All-flash

ceph config set osd osd_max_scrubs 3
ceph config set osd osd_scrub_sleep 0
# no time window — flash absorbs the load

Archive, throughput-oriented

ceph config set osd osd_max_scrubs 2
ceph config set osd osd_deep_scrub_interval 604800
# scrub matters most here; cold data has no other check

Verifying the intent

# is the schedule keeping up?
ceph health detail | grep -E 'NOT_SCRUBBED|NOT_DEEP_SCRUBBED'

# how old is the oldest?
ceph pg dump pgs 2>/dev/null | awk 'NR>1 {print $23}' | sort | head -1

# is the concurrency being used?
ceph pg dump pgs 2>/dev/null | grep -c scrubbing

If no PGs are ever scrubbing during the window, the load threshold is never met and the configuration is not achieving its intent regardless of what the settings say.

Quiz

Knowledge check · 4 questions

  1. Q1. On an HDD cluster, why is `osd_scrub_sleep` often more effective than lowering `osd_max_scrubs`?

  2. Q2. A scratch pool and a compliance archive on one cluster need opposite scrub policies.

  3. Q3. Configure scrub for a mixed cluster.

    A cluster hosts an all-NVMe pool for databases, an HDD pool for VM backups, and an HDD pool for a compliance archive that is read perhaps twice a year. One cluster-wide scrub configuration is in place.

  4. Q4. How do you tell whether a scrub configuration is achieving its intent?

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

Production discipline

Use per-pool scrub settings where pools have different requirements; a single cluster-wide interval serves the read-light archive and the scratch pool equally badly. On HDD reach for osd_scrub_sleep before lowering concurrency, and verify the configuration by the stamps rather than by the settings.

Cross-course references

  • Kubernetes: per-namespace resource policy expresses what cluster defaults cannot
  • Linux: per-filesystem scrub schedules serve the same differentiation