Skip to main content
RunBook Academy

CephCXXIII · Capacity and Failure PlanningCapacity and Failure Planning

Working the numbers to an order

Advanced⏱ ~18 minceph

What you'll learn

  • Assemble the worksheet from cluster figures
  • Work an example through to an order date and quantity
  • Compute the placement group budget as a second constraint
  • Present both constraints together

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

A capacity plan that does not end in a date and a quantity is a description. These are the lines that turn it into an order.

The worksheet

LineWhere it comes from
Usable capacity USTORED plus MAX AVAIL in ceph df detail
Hosts N, per-host usable uu equals U divided by N
Live dataSTORED across the pools
Failure reserveu, or twice u if the policy allows overlap
Allocatableu times N minus one
Growth allowanceallocatable minus live data
Daily growthmeasured drift plus committed step changes
Days to reserve crossingallowance divided by daily growth
Lead-time chaindecision through to completed backfill
Order datetoday plus days to crossing minus the chain

Working an example

U = 118 TiB over 6 hosts          u = 19.7 TiB per host
live = 70 TiB                     growth = 180 GiB/day
allocatable = 19.7 x 5          = 98.3 TiB
allowance   = 98.3 - 70         = 28.3 TiB
days to reserve crossing        = 28.3 x 1024 / 180 = 161 days
lead-time chain                 = 75 days
order by                        = day 86

Each host added contributes exactly u to the allowance, because the reserve also stays at one host worth.

Hosts addedAllowanceDays of runway
028.3 TiB161
148.0 TiB273
267.7 TiB385
387.3 TiB497

Two hosts buys roughly a year. That is the quantity.

The second budget, counted in placement groups

ceph config get mon mon_target_pg_per_osd
ceph config get mon mon_max_pg_per_osd
ceph config get osd osd_max_pg_per_osd_hard_ratio
ceph osd pool autoscale-status
ceph osd dump -f json | python3 -c '
import sys,json
d = json.load(sys.stdin)
osds = len([o for o in d["osds"] if o["in"]])
tot  = sum(p["pg_num"] * p["size"] for p in d["pools"])
print("pools %d  pg replicas %d  osds %d  per osd %.1f" %
      (len(d["pools"]), tot, osds, tot/osds))'
ClusterBudget at 100 per OSDSeven RGW pools at 32 PGs, size 3
3 hosts, 9 OSDs900 PG replicas672 — three quarters of the budget
6 hosts, 48 OSDs4800 PG replicas672 — about a seventh

What the answer looks like

Order 2 hosts by 2026-11-12. Runway after backfill: 385 days.
Constraint checked: PG budget 3075 replicas over 48 OSDs, 64 per OSD.
Adding RGW would add 672 replicas, taking it to 78 per OSD. Fits.

Quiz

Knowledge check · 4 questions

  1. Q1. On a six-host cluster with 19.7 TiB usable per host and 70 TiB live, what is the growth allowance?

  2. Q2. Free capacity and the placement group budget are independent constraints, and either can block a new pool.

  3. Q3. Produce an order date and a quantity from cluster figures.

    Six hosts, 118 TiB usable, 70 TiB live, growing 180 GiB per day. The lead-time chain measures 75 days. The team wants at least a year of runway after the new capacity is in service.

  4. Q4. Why can a small cluster refuse a new pool while holding plenty of free space?

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

Production discipline

End every capacity review with a date and a quantity, and show the identity that produced them — allocatable is one host worth times the host count minus one. Check the placement group budget in the same review, because the refusal it produces arrives during a deployment rather than during planning.

Cross-course references

  • Kubernetes: pods per node is a count limit that binds long before CPU or memory does
  • Linux: inode exhaustion refuses writes on a filesystem with free blocks for the same reason