CephXXI · PG AutoscalePG Autoscale
Bounding what the autoscaler may do
What you'll learn
- Apply pg_num_min and pg_num_max to bound a pool
- Use the bulk flag and bias appropriately
- Adjust the global PG-per-OSD target
- Design an autoscaling policy for a mixed cluster
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
on versus warn is a blunt instrument: either the module acts or it
does not. The interesting middle ground is letting it act within limits
you set. That is what the bounding controls are for, and using them well
means you can leave autoscaling enabled on pools you would otherwise have
to babysit.
Hard bounds
ceph osd pool set cephfs-meta pg_num_min 256
ceph osd pool set scratch pg_num_max 512
pg_num_min is a floor. The classic use is CephFS metadata: it holds
almost no bytes, so the module wants to give it the minimum, but its
access pattern is small-random and it benefits from spreading across many
OSDs. A floor encodes “this pool needs parallelism even though it needs no
space.”
pg_num_max is a ceiling. Use it on pools that could grow unexpectedly —
a scratch or staging pool — where you would rather cap the PG count than
discover the OSDs are carrying thousands of PGs each.
The bulk flag
ceph osd pool set s3-archive bulk true
bulk tells the module “this pool is expected to consume a large share of
the cluster, so start it at a large PG count instead of growing into
one.” Without it, a pool starts near the minimum and gets split repeatedly
as it fills — each split costing data movement. With it, the pool is sized
for its destiny on day one and grows into a stable layout.
Set it at pool creation for anything you know will be large:
ceph osd pool create s3-archive --bulk
bias
ceph osd pool set cephfs-meta pg_autoscale_bias 4.0
bias multiplies the computed PG count for a pool. It is the soft version
of pg_num_min: instead of pinning a floor, you tell the module this pool
deserves more PGs per byte than its size suggests. Metadata pools are
again the canonical case — Ceph sets a bias on CephFS metadata pools by
default for exactly this reason.
Use bias when the ratio is wrong; use pg_num_min when you need a
specific guaranteed value.
The global budget
ceph config set global mon_target_pg_per_osd 100
This is the number the whole calculation hangs from. Raising it gives every pool more PGs; lowering it gives every pool fewer. The default of 100 is a good balance for most hardware. Raise it toward 200 only on all-flash clusters with generous OSD memory, and expect the per-OSD memory and CPU cost to rise with it.
There is a related guard rail:
ceph config set global mon_max_pg_per_osd 250
which is a hard limit — exceed it and pool creation or PG increases are
refused, with TOO_MANY_PGS in the health output.
Quiz
Knowledge check · 4 questions
Q1. A CephFS metadata pool holds 12 GB but serves heavy small-random metadata traffic. Which control best expresses "this pool needs more PGs than its size implies"?
Q2. The bulk flag causes a pool to start at a large PG count rather than growing into one through repeated splits.
Q3. Design an autoscaling policy for a mixed cluster.
A 200-OSD cluster hosts: `rbd-vms` (production VMs, strict latency SLO), `cephfs-meta` and `cephfs-data` (shared filesystem), `s3-archive` (EC, growing to hundreds of TB), and `ci-scratch` (used by build jobs, unpredictable and occasionally enormous).
Q4. Why is raising mon_target_pg_per_osd from 100 to 300 across the cluster risky even on fast hardware?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Bounds are how you make autoscaling auditable. A pool with
pg_num_min, pg_num_max, or a bias set carries a visible statement of
intent that survives staff turnover, whereas a pool someone manually
pinned looks identical to one nobody thought about. Review the bounds
whenever the cluster’s OSD count changes materially, and check
mon_max_pg_per_osd headroom before large pool creations.
Cross-course references
- Kubernetes: LimitRange and ResourceQuota play the same role — bounding an autonomous controller’s decisions
- Linux: cgroup limits around an automatic process are the same pattern of bounded autonomy