Skip to main content
RunBook Academy

CephXXVI · Erasure Coding Trade-offsErasure Coding Trade-offs

Capacity planning for erasure-coded pools

Advanced⏱ ~18 minceph

What you'll learn

  • Compute usable capacity from raw for any EC profile
  • Apply fill and failure-domain reserves correctly
  • Model growth against the reserve thresholds
  • Produce a defensible capacity plan document

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 quotes raw capacity divided by the EC ratio is wrong by 30–40%, and the error surfaces when the cluster is nearly full — the worst possible moment. Working the reserves explicitly is what makes the number usable.

The full derivation

Start from raw and subtract each reserve in turn.

Step 1 — raw to EC-usable.

raw = 1,200 TB
profile 8+3 → ratio 1.375
EC-usable = 1200 / 1.375 = 873 TB

Step 2 — fill headroom. Ceph warns at nearfull (0.85) and stops writes at full (0.95), and OSDs are never perfectly balanced, so the fullest OSD hits the threshold before the average does.

target average fill: 0.75
usable after headroom = 873 × 0.75 = 655 TB

Step 3 — failure reserve. After a host fails, its data is redistributed across the survivors. That capacity must already exist.

14 hosts, lose 1 → survivors must absorb 1/14 ≈ 7.1%
usable after failure reserve = 655 × (1 − 0.071) = 608 TB

Step 4 — growth margin. Adding capacity takes procurement time. Leave enough that you trigger the purchase before the reserves are consumed.

6-month growth at observed rate: 90 TB
plan to fill to 608 − 90 = 518 TB before ordering

So 1.2 PB raw plans to roughly 520 TB of committed user data on 8+3 — not the 873 TB the ratio alone suggests.

Reading actual usage

ceph df
ceph df detail
ceph osd df                     # per-OSD, and the variance that matters
ceph osd pool autoscale-status  # RATE column confirms the ratio

ceph df reports STORED (user bytes) and USED (raw bytes) per pool. Their ratio is your real, measured overhead including allocation waste — compare it against the profile ratio to catch a small-object problem early.

The variance trap

ceph osd df | awk '{print $17}' | sort -n | tail -5

If the fullest OSD is 15 points above the average, your effective capacity is set by that OSD, not by the average. Run the balancer and re-measure before finalising the plan:

ceph balancer status
ceph balancer mode upmap
ceph balancer on

Quiz

Knowledge check · 4 questions

  1. Q1. A cluster has 900 TB raw on an EC 6+3 profile. Roughly what should the capacity plan commit to, after fill headroom and a single-host failure reserve on 12 hosts?

  2. Q2. The USED/STORED ratio in ceph df should match the profile ratio closely on a pool of small objects.

  3. Q3. Explain a capacity shortfall discovered at 70% fill.

    A team planned 600 TB of usable capacity on an EC 4+2 pool with 900 TB raw. At what `ceph df` reports as 70% pool utilisation, one OSD has crossed nearfull and writes to some PGs are being refused. Average OSD utilisation is 71%; the fullest is 88%.

  4. Q4. Why does OSD utilisation variance reduce effective capacity below the average-based calculation?

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

Production discipline

Publish the capacity plan with every reserve shown as a separate line so reviewers can see and challenge each assumption. Track the measured USED/STORED ratio over time — a rising figure means object sizes are shrinking and the plan needs revisiting before the reserves absorb the difference. Alert on OSD utilisation variance alongside average utilisation.

Cross-course references

  • Kubernetes: cluster capacity planning has the identical structure of nominal capacity minus reserves
  • Linux: filesystem reserved blocks exist for exactly the same reason as the fill headroom