{
  "schemaVersion": 1,
  "slug": "parity-declustering-load",
  "title": "Parity declustering: survivor-read accounting",
  "summary": "Twenty-one exact survivor rows compare fixed and balanced width-four groups with a width-eight control. Synthetic accounting, not storage measurements.",
  "published": "2026-10-13",
  "updated": "2026-10-13",
  "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/parity-declustering-rebuild-load/",
  "humanPage": "https://hesela.com/analyses/parity-declustering-rebuild-load/",
  "downloadPath": "/data/datasets/parity-declustering-load.csv",
  "codePath": "/research/parity-declustering.mjs",
  "generatorPath": "/research/build-parity-declustering.mjs",
  "rowCount": 21,
  "columns": [
    {
      "name": "layout",
      "type": "string",
      "description": "Synthetic stripe-membership layout ID."
    },
    {
      "name": "poolDisks",
      "type": "number",
      "description": "Number of disks in the modeled pool, including the failed disk."
    },
    {
      "name": "groupWidth",
      "type": "number",
      "description": "Fragments per single-parity stripe, including one parity fragment."
    },
    {
      "name": "failedDisk",
      "type": "number",
      "description": "Zero-based disk ID lost in this scenario; always 0 in this export."
    },
    {
      "name": "survivorDisk",
      "type": "number",
      "description": "Zero-based surviving disk ID; includes disks doing zero reads."
    },
    {
      "name": "lostBlocks",
      "type": "number",
      "description": "Fragments lost on the failed disk; each is independently reconstructed."
    },
    {
      "name": "survivorHeldBlocks",
      "type": "number",
      "description": "Fragments held on this survivor before failure, including parity."
    },
    {
      "name": "readBlocks",
      "type": "number",
      "description": "Whole helper fragments read from this survivor for complete modeled repair."
    },
    {
      "name": "fragmentBytes",
      "type": "number",
      "description": "Bytes per fragment; 67108864 bytes = 64 MiB."
    },
    {
      "name": "readBytes",
      "type": "number",
      "description": "readBlocks multiplied by fragmentBytes; excludes reconstructed writes."
    }
  ],
  "method": "Enumerate all 70 four-disk subsets of eight disks for the balanced layout. Repeat each of two disjoint four-disk groups 35 times for the fixed control; repeat the eight-disk group 35 times for the wide control. Each disk holds 35 equal 64 MiB fragments. For each stripe containing failed disk 0, count one read from each intact member. A stripe has exactly one parity fragment; its position is irrelevant to this single-erasure read count.",
  "limits": [
    "This is exhaustive deterministic enumeration, not a random sample, benchmark or field dataset; there is no observation period or statistical confidence interval.",
    "Eight modeled disks, one known erasure, intact helpers and equal-size fragments; no read failures, duplicate reads, compression, caches or metadata traffic.",
    "Output writes total 35 fragments in each case but their destination and timing are not modeled.",
    "The wide control changes parity overhead and payload capacity as well as stripe width. Fixed and balanced width-four cases are the matched comparison.",
    "Stripe membership is not a full physical layout: no parity rotation, addresses, encoder, queue model or OpenZFS permutation map.",
    "The model bounds pool size to 16 to prevent uncontrolled combinatorial enumeration. Complete layouts are educational examples, not a production recommendation."
  ],
  "citations": [
    {
      "id": "holland1992",
      "title": "Mark Holland and Garth A. Gibson. Parity Declustering for Continuous Operation in Redundant Disk Arrays. ASPLOS 1992, pp. 23-35; sections 2, 4-8.",
      "url": "https://www.cs.cmu.edu/~riedel/ftp/Declustering/ASPLOS.pdf",
      "accessed": "2026-10-13"
    },
    {
      "id": "welch2008",
      "title": "Brent Welch, Marc Unangst, Zainul Abbasi, Garth Gibson, Brian Mueller, Jason Small, Jim Zelenka and Bin Zhou. Scalable Performance of the Panasas Parallel File System. FAST 2008; section 4.2 and Appendix A, experiment 3.",
      "url": "https://www.usenix.org/legacy/event/fast08/tech/full_papers/welch/welch_html/index.html",
      "accessed": "2026-10-13"
    },
    {
      "id": "openzfs",
      "title": "OpenZFS: dRAID how-to, Introduction and Rebuilding to a Distributed Spare (living documentation, functionality introduced in 2.1.0).",
      "url": "https://openzfs.github.io/openzfs-docs/Basic%20Concepts/Pool%20Structure/dRAID%20Howto.html",
      "accessed": "2026-10-13"
    }
  ],
  "generatedAt": "2026-10-12T23:22:01.156Z",
  "artifacts": {
    "modelSha256": "0e7372c99ccf735d977500216f0a69996ccaababc1dfa4d579fd7f95aafc100a",
    "csvSha256": "1a08ab919d67a8800f369db13c6ac480f90ca0d57feae76dcaa2314a22f2adf7"
  },
  "summaries": [
    {
      "id": "fixed-4-of-8",
      "label": "Two fixed groups, width 4",
      "poolDisks": 8,
      "groupWidth": 4,
      "stripeCount": 70,
      "parityFraction": 0.25,
      "failedDisk": 0,
      "fragmentBytes": 67108864,
      "held": [
        35,
        35,
        35,
        35,
        35,
        35,
        35,
        35
      ],
      "reads": [
        0,
        35,
        35,
        35,
        0,
        0,
        0,
        0
      ],
      "lostBlocks": 35,
      "totalReads": 105,
      "readBytes": 7046430720,
      "reconstructedBytes": 2348810240
    },
    {
      "id": "balanced-4-of-8",
      "label": "Balanced groups, width 4",
      "poolDisks": 8,
      "groupWidth": 4,
      "stripeCount": 70,
      "parityFraction": 0.25,
      "failedDisk": 0,
      "fragmentBytes": 67108864,
      "held": [
        35,
        35,
        35,
        35,
        35,
        35,
        35,
        35
      ],
      "reads": [
        0,
        15,
        15,
        15,
        15,
        15,
        15,
        15
      ],
      "lostBlocks": 35,
      "totalReads": 105,
      "readBytes": 7046430720,
      "reconstructedBytes": 2348810240
    },
    {
      "id": "wide-8-of-8",
      "label": "One wide group, width 8",
      "poolDisks": 8,
      "groupWidth": 8,
      "stripeCount": 35,
      "parityFraction": 0.125,
      "failedDisk": 0,
      "fragmentBytes": 67108864,
      "held": [
        35,
        35,
        35,
        35,
        35,
        35,
        35,
        35
      ],
      "reads": [
        0,
        35,
        35,
        35,
        35,
        35,
        35,
        35
      ],
      "lostBlocks": 35,
      "totalReads": 245,
      "readBytes": 16441671680,
      "reconstructedBytes": 2348810240
    }
  ],
  "rows": [
    {
      "layout": "fixed-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 1,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "fixed-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 2,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "fixed-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 3,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "fixed-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 4,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 0,
      "fragmentBytes": 67108864,
      "readBytes": 0
    },
    {
      "layout": "fixed-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 5,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 0,
      "fragmentBytes": 67108864,
      "readBytes": 0
    },
    {
      "layout": "fixed-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 6,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 0,
      "fragmentBytes": 67108864,
      "readBytes": 0
    },
    {
      "layout": "fixed-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 7,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 0,
      "fragmentBytes": 67108864,
      "readBytes": 0
    },
    {
      "layout": "balanced-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 1,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 15,
      "fragmentBytes": 67108864,
      "readBytes": 1006632960
    },
    {
      "layout": "balanced-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 2,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 15,
      "fragmentBytes": 67108864,
      "readBytes": 1006632960
    },
    {
      "layout": "balanced-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 3,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 15,
      "fragmentBytes": 67108864,
      "readBytes": 1006632960
    },
    {
      "layout": "balanced-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 4,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 15,
      "fragmentBytes": 67108864,
      "readBytes": 1006632960
    },
    {
      "layout": "balanced-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 5,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 15,
      "fragmentBytes": 67108864,
      "readBytes": 1006632960
    },
    {
      "layout": "balanced-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 6,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 15,
      "fragmentBytes": 67108864,
      "readBytes": 1006632960
    },
    {
      "layout": "balanced-4-of-8",
      "poolDisks": 8,
      "groupWidth": 4,
      "failedDisk": 0,
      "survivorDisk": 7,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 15,
      "fragmentBytes": 67108864,
      "readBytes": 1006632960
    },
    {
      "layout": "wide-8-of-8",
      "poolDisks": 8,
      "groupWidth": 8,
      "failedDisk": 0,
      "survivorDisk": 1,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "wide-8-of-8",
      "poolDisks": 8,
      "groupWidth": 8,
      "failedDisk": 0,
      "survivorDisk": 2,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "wide-8-of-8",
      "poolDisks": 8,
      "groupWidth": 8,
      "failedDisk": 0,
      "survivorDisk": 3,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "wide-8-of-8",
      "poolDisks": 8,
      "groupWidth": 8,
      "failedDisk": 0,
      "survivorDisk": 4,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "wide-8-of-8",
      "poolDisks": 8,
      "groupWidth": 8,
      "failedDisk": 0,
      "survivorDisk": 5,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "wide-8-of-8",
      "poolDisks": 8,
      "groupWidth": 8,
      "failedDisk": 0,
      "survivorDisk": 6,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    },
    {
      "layout": "wide-8-of-8",
      "poolDisks": 8,
      "groupWidth": 8,
      "failedDisk": 0,
      "survivorDisk": 7,
      "lostBlocks": 35,
      "survivorHeldBlocks": 35,
      "readBlocks": 35,
      "fragmentBytes": 67108864,
      "readBytes": 2348810240
    }
  ]
}
