{
  "schemaVersion": 1,
  "slug": "raidz-expansion-overhead",
  "title": "RAIDZ expansion: ideal retained parity overhead",
  "summary": "Five deterministic mixtures of old and new full-width parity geometry for the same 6 TiB payload. Not measured storage capacity or ZFS space-report output.",
  "published": "2026-10-16",
  "updated": "2026-10-16",
  "evidenceType": "deterministic-accounting-model",
  "license": "CC0-1.0 for Hesela's original model and generated data; cited sources retain their own rights.",
  "licenseUrl": "https://creativecommons.org/publicdomain/zero/1.0/",
  "sourceUrl": "https://hesela.com/analyses/raidz-expansion-parity-capacity/",
  "humanPage": "https://hesela.com/analyses/raidz-expansion-parity-capacity/",
  "downloadPath": "/data/datasets/raidz-expansion-overhead.csv",
  "codePath": "/research/raidz-expansion.mjs",
  "generatorPath": "/research/build-raidz-expansion.mjs",
  "rowCount": 5,
  "columns": [
    {
      "name": "oldWidth",
      "type": "number",
      "description": "Original physical width, including parity; 4 in this example."
    },
    {
      "name": "newWidth",
      "type": "number",
      "description": "Final physical width, including parity; 5 in this example."
    },
    {
      "name": "parity",
      "type": "number",
      "description": "Unchanged parity-fragment count per full row; 2."
    },
    {
      "name": "payloadTiB",
      "type": "number",
      "description": "Total payload in TiB (2^40 bytes), excluding parity; 6."
    },
    {
      "name": "oldFraction",
      "type": "number",
      "description": "Fraction of payload bytes retaining the old data-to-parity ratio, not pool occupancy."
    },
    {
      "name": "oldPayloadTiB",
      "type": "number",
      "description": "Payload at the old ratio, in TiB."
    },
    {
      "name": "newPayloadTiB",
      "type": "number",
      "description": "Payload at the new ratio, in TiB."
    },
    {
      "name": "oldParityTiB",
      "type": "number",
      "description": "Ideal parity allocated for the old cohort, in TiB."
    },
    {
      "name": "newParityTiB",
      "type": "number",
      "description": "Ideal parity allocated for the new cohort, in TiB."
    },
    {
      "name": "rawTiB",
      "type": "number",
      "description": "Modeled total payload plus parity, in TiB; not zfs list or zpool list output."
    },
    {
      "name": "allNewRawTiB",
      "type": "number",
      "description": "Counterfactual allocation if all payload used the new ratio and old blocks were freed, in TiB."
    },
    {
      "name": "retainedExtraTiB",
      "type": "number",
      "description": "Extra allocation relative to that all-new counterfactual, in TiB; not promised reclaimable space."
    }
  ],
  "method": "Hold payload D=6 TiB and parity P=2 fixed; old width N=4, new width M=5. Enumerate old payload fractions f=0,0.25,0.5,0.75,1. Compute raw=D*f*N/(N-P)+D*(1-f)*M/(M-P); extra=D*f*P*(M-N)/((N-P)*(M-P)). TiB means 2^40 bytes. CSV rounds numbers to nine decimal places; the in-page table uses these exact half-TiB example values. Each row is an independent hypothetical cohort mixture, not an observed time step.",
  "limits": [
    "This is deterministic algebra, not a hardware benchmark, field dataset or replication of FastScale; no observation period, sampling interval or statistical confidence interval applies.",
    "Assumes full-width equal-size fragments, fixed payload and unchanged parity. Real RAIDZ blocks can use variable widths and incur allocation padding.",
    "Excludes metadata, compression, deduplication, snapshots, clones, reservations, free-space headroom and filesystem accounting conventions.",
    "The all-new counterfactual assumes old blocks are freed. Retained snapshot or clone references can make a rewrite consume additional space.",
    "Multiple historical expansion widths require separate cohort accounting; this export contains only one old and one new geometry.",
    "No prediction of rewrite duration, error rate, recoverability, actual usable capacity or reported AVAIL."
  ],
  "citations": [
    {
      "id": "attach",
      "title": "OpenZFS 2.3: zpool-attach(8), RAID-Z expansion and space reporting",
      "url": "https://openzfs.github.io/openzfs-docs/man/v2.3/8/zpool-attach.8.html",
      "accessed": "2026-10-16"
    },
    {
      "id": "rewrite",
      "title": "OpenZFS zfs-2.3.4: zfs-rewrite(8), snapshot and clone space consequences",
      "url": "https://github.com/openzfs/zfs/blob/zfs-2.3.4/man/man8/zfs-rewrite.8",
      "accessed": "2026-10-16"
    },
    {
      "id": "concepts",
      "title": "OpenZFS zfs-2.3.0: zpoolconcepts(7), RAID-Z virtual devices",
      "url": "https://github.com/openzfs/zfs/blob/zfs-2.3.0/man/man7/zpoolconcepts.7",
      "accessed": "2026-10-16"
    }
  ],
  "generatedAt": "2026-10-16T08:41:22.503Z",
  "artifacts": {
    "modelSha256": "81aaac354ccb1e410e9fe04a567631db1f619fd74f32863a92752fb731a426ae",
    "csvSha256": "6e86b2036d7e9a7b7d3b019f4d7e3f1d6c8b9b84e3aef35be8bc6f9e7a0641d4"
  },
  "rows": [
    {
      "oldWidth": 4,
      "newWidth": 5,
      "parity": 2,
      "payloadTiB": 6,
      "oldFraction": 0,
      "oldPayloadTiB": 0,
      "newPayloadTiB": 6,
      "oldParityTiB": 0,
      "newParityTiB": 4,
      "rawTiB": 10,
      "allNewRawTiB": 10,
      "retainedExtraTiB": 0
    },
    {
      "oldWidth": 4,
      "newWidth": 5,
      "parity": 2,
      "payloadTiB": 6,
      "oldFraction": 0.25,
      "oldPayloadTiB": 1.5,
      "newPayloadTiB": 4.5,
      "oldParityTiB": 1.5,
      "newParityTiB": 3,
      "rawTiB": 10.5,
      "allNewRawTiB": 10,
      "retainedExtraTiB": 0.5
    },
    {
      "oldWidth": 4,
      "newWidth": 5,
      "parity": 2,
      "payloadTiB": 6,
      "oldFraction": 0.5,
      "oldPayloadTiB": 3,
      "newPayloadTiB": 3,
      "oldParityTiB": 3,
      "newParityTiB": 2,
      "rawTiB": 11,
      "allNewRawTiB": 10,
      "retainedExtraTiB": 1
    },
    {
      "oldWidth": 4,
      "newWidth": 5,
      "parity": 2,
      "payloadTiB": 6,
      "oldFraction": 0.75,
      "oldPayloadTiB": 4.5,
      "newPayloadTiB": 1.5,
      "oldParityTiB": 4.5,
      "newParityTiB": 1,
      "rawTiB": 11.5,
      "allNewRawTiB": 10,
      "retainedExtraTiB": 1.5
    },
    {
      "oldWidth": 4,
      "newWidth": 5,
      "parity": 2,
      "payloadTiB": 6,
      "oldFraction": 1,
      "oldPayloadTiB": 6,
      "newPayloadTiB": 0,
      "oldParityTiB": 6,
      "newParityTiB": 0,
      "rawTiB": 12,
      "allNewRawTiB": 10,
      "retainedExtraTiB": 2
    }
  ]
}
