{
  "schemaVersion": 1,
  "slug": "lrc-repair-costs",
  "title": "LRC repair costs: explicit denominators",
  "summary": "Five deterministic whole-fragment examples distinguish data repair, all-fragment averages and parity-inclusive accounting. Not cluster measurements.",
  "published": "2026-10-11",
  "updated": "2026-10-11",
  "generatedAt": "2026-10-11T18:21:35.531Z",
  "evidenceType": "deterministic-accounting-model",
  "license": "CC0-1.0 for Hesela's original model and generated rows. Cited publications retain their own rights.",
  "licenseUrl": "https://creativecommons.org/publicdomain/zero/1.0/",
  "sourceUrl": "https://hesela.com/analyses/lrc-repair-costs-locality/",
  "humanPage": "https://hesela.com/analyses/lrc-repair-costs-locality/",
  "downloadPath": "/data/datasets/lrc-repair-costs.csv",
  "codePath": "/research/lrc-repair-costs.mjs",
  "rowCount": 5,
  "columns": [
    {
      "name": "label",
      "type": "string",
      "description": "RS uses data+global parity; LRC uses data+local parity+global parity. Not Ceph CLI notation."
    },
    {
      "name": "k",
      "type": "number",
      "description": "Number of payload data fragments per stripe."
    },
    {
      "name": "localGroups",
      "type": "number",
      "description": "Equal data groups, each with one local parity; zero for the RS baseline."
    },
    {
      "name": "globalParities",
      "type": "number",
      "description": "Number of global parity fragments."
    },
    {
      "name": "totalFragments",
      "type": "number",
      "description": "Total stored fragments: data plus all parity."
    },
    {
      "name": "shardBytes",
      "type": "number",
      "description": "Bytes per equal-size fragment. Illustrative input; 1 MiB = 1048576 bytes."
    },
    {
      "name": "storageFactor",
      "type": "number",
      "description": "Stored bytes divided by payload bytes; dimensionless, excluding metadata."
    },
    {
      "name": "dataReads",
      "type": "number",
      "description": "Complete helper fragments read for one data-fragment loss."
    },
    {
      "name": "localParityReads",
      "type": "number",
      "description": "Complete helper fragments read for one local-parity loss; zero means not applicable in RS."
    },
    {
      "name": "globalParityReads",
      "type": "number",
      "description": "Complete helper fragments read to recompute one global parity."
    },
    {
      "name": "sumIndependentReads",
      "type": "number",
      "description": "Sum of independent one-fragment repair read counts across every position; not simultaneous losses."
    },
    {
      "name": "averageReadsPerLostFragment",
      "type": "number",
      "description": "Sum of independent read counts divided by total stored fragments; uniform lost-role assumption."
    },
    {
      "name": "readsPerLostDataEquivalent",
      "type": "number",
      "description": "Same sum divided by payload data fragments; parity repairs amortized over payload."
    },
    {
      "name": "dataReadBytes",
      "type": "number",
      "description": "Helper bytes read for one data-fragment loss, excluding the reconstructed write."
    }
  ],
  "method": "For each independent single-fragment loss, intact helpers supply whole equal-size fragments. Data and local parity cost k/localGroups reads in the modeled LRC topology; global parity costs k. RS costs k for any fragment. Sum costs across all positions, then divide by total fragments or by k. Uniform role distribution is assumed for node-level interpretation.",
  "limits": [
    "Arithmetic examples, not experiments, event probabilities or confidence intervals.",
    "Not an encoder or decoder; no proof of a concrete finite-field construction or multi-erasure recovery.",
    "Equal overhead is not equal worst-case erasure tolerance. No current Azure or Ceph configuration is asserted.",
    "No partial-fragment schemes, shared reads, caching, retries, placement, compression, network topology or reconstructed-write traffic.",
    "These sums represent separate single-fragment failures across stripe roles, never simultaneous loss of all fragments."
  ],
  "citations": [
    {
      "id": "huang2012",
      "title": "Cheng Huang, Huseyin Simitci, Yikang Xu, Aaron Ogus, Brad Calder, Parikshit Gopalan, Jin Li and Sergey Yekhanin. Erasure Coding in Windows Azure Storage. USENIX ATC 2012, pp. 15-26; sections 2-3.",
      "url": "https://www.usenix.org/system/files/conference/atc12/atc12-final181_0.pdf",
      "accessed": "2026-10-11"
    },
    {
      "id": "kolosov2018",
      "title": "Oleg Kolosov, Gala Yadgar, Matan Liram, Itzhak Tamo and Alexander Barg. On Fault Tolerance, Locality, and Optimality in Locally Repairable Codes. USENIX ATC 2018, pp. 865-877; sections 3, 5-6.",
      "url": "https://www.usenix.org/system/files/conference/atc18/atc18-kolosov.pdf",
      "accessed": "2026-10-11"
    },
    {
      "id": "ceph-lrc",
      "title": "Ceph: Locally Repairable Erasure Code Plugin (development documentation; parameter names are implementation-specific).",
      "url": "https://docs.ceph.com/en/latest/rados/operations/erasure-code-lrc/",
      "accessed": "2026-10-11"
    }
  ],
  "artifacts": {
    "modelSha256": "b50b841379428d180cf385e0ff758896cc817ad2ac388e8bb016455efd0888f2",
    "csvSha256": "b32f8ccba7b30416bbe8b00c3463166c3bc491963dba555eea82c9098b6011fa"
  },
  "rows": [
    {
      "label": "RS 6+3",
      "k": 6,
      "localGroups": 0,
      "globalParities": 3,
      "totalFragments": 9,
      "shardBytes": 67108864,
      "storageFactor": 1.5,
      "dataReads": 6,
      "localParityReads": 0,
      "globalParityReads": 6,
      "sumIndependentReads": 54,
      "averageReadsPerLostFragment": 6,
      "readsPerLostDataEquivalent": 9,
      "dataReadBytes": 402653184
    },
    {
      "label": "RS 12+4",
      "k": 12,
      "localGroups": 0,
      "globalParities": 4,
      "totalFragments": 16,
      "shardBytes": 67108864,
      "storageFactor": 1.3333333333333333,
      "dataReads": 12,
      "localParityReads": 0,
      "globalParityReads": 12,
      "sumIndependentReads": 192,
      "averageReadsPerLostFragment": 12,
      "readsPerLostDataEquivalent": 16,
      "dataReadBytes": 805306368
    },
    {
      "label": "LRC 6+2+2",
      "k": 6,
      "localGroups": 2,
      "globalParities": 2,
      "totalFragments": 10,
      "shardBytes": 67108864,
      "storageFactor": 1.6666666666666667,
      "dataReads": 3,
      "localParityReads": 3,
      "globalParityReads": 6,
      "sumIndependentReads": 36,
      "averageReadsPerLostFragment": 3.6,
      "readsPerLostDataEquivalent": 6,
      "dataReadBytes": 201326592
    },
    {
      "label": "LRC 12+2+2",
      "k": 12,
      "localGroups": 2,
      "globalParities": 2,
      "totalFragments": 16,
      "shardBytes": 67108864,
      "storageFactor": 1.3333333333333333,
      "dataReads": 6,
      "localParityReads": 6,
      "globalParityReads": 12,
      "sumIndependentReads": 108,
      "averageReadsPerLostFragment": 6.75,
      "readsPerLostDataEquivalent": 9,
      "dataReadBytes": 402653184
    },
    {
      "label": "LRC 12+4+2",
      "k": 12,
      "localGroups": 4,
      "globalParities": 2,
      "totalFragments": 18,
      "shardBytes": 67108864,
      "storageFactor": 1.5,
      "dataReads": 3,
      "localParityReads": 3,
      "globalParityReads": 12,
      "sumIndependentReads": 72,
      "averageReadsPerLostFragment": 4,
      "readsPerLostDataEquivalent": 6,
      "dataReadBytes": 201326592
    }
  ]
}
