A methods explainer · 3 minutes
18.5% – 24.1%
confirmed diverted — a range, not a number
We wanted to answer one question: where does LA’s commercial waste go? The records exist; the City receives them every month. This is the story of why the honest answer is a range — and the five sentences of reporting law that would change that.
or just scroll
Step one · parse
A Public Records Act request produced one spreadsheet: three years of RecycLA hauler tonnage reports — 4,828,942 tons, once parsed. Step one was discovering that 25,486 lines of text are 20,518 rows of data — some fields contain line breaks, so rows wrap mid-record.
Every count in this piece had to be earned like that. A ledger accounts for all 20,518 parsed rows — 100%, no silent drops.
| Period | RSP | Zone | Bin | Commodity | Facility | Next destination | Tons |
|---|---|---|---|---|---|---|---|
| 1/1/22 | Athens | F-HB | Black | Mixed Solid Waste (MSW) | Athens Services (Industry) | Mid-Valley Landfill | 30.08 |
| 1/1/22 | Athens | F-WLA | Black | Mixed Solid Waste (MSW) | Athens Sun Valley MRF & TS | Chiquita Canyon Landfill | 348.65 |
| 1/1/22 | CalMet | F-EDT | Black | Mixed Solid Waste (MSW) | Central Los Angeles Recycling Center & Transfer Station | 620.71 | |
| 1/1/22 | CalMet | F-EDT | Blue | Commingled Recyclables | Universal Resource Recovery | 230.09 | |
| 1/1/22 | NASA | F-DT | Black | Mixed Solid Waste (MSW) | Puente Hills Materials Recovery Facility | Frank G Bowerman ⏎ | 38.3 |
| 1/1/22 | NASA | F-DT | Black | Mixed Solid Waste (MSW) | Central Los Angeles Recycling Center & Transfer Station | El Sobrante and Chiquita Canyon ⏎ | 967.14 |
| 1/1/22 | UWS | F-NE | Green | Food Waste | Sun Valley Recycling Park | 28.69 | |
| 1/1/22 | WM | F-SEV | Blue | Commingled Recyclables | Simi Valley Landfill and Recycling Center | Sun Valley Recycle Park | 0.59 |
| 1/1/24 | Athens | F-HB | Green | Mixed Organics | Downey Area Recycling and Transfer Facility (DART) | Crown Recycling Services ⏎ | 193.12 |
wc -l) → 20,518 parsed rows (embedded newlines rejoined).The first surprise
Exactly half the rows — 10,259 of 20,518 — aren’t loads at all. They’re a zone × bin summary pivot table appended below the data, with no marker saying so.
We reconciled all 45 of its cell totals against the real rows: they match to the cent, cell by cell; the panel’s grand total is 4,828,072.27. The export is internally honest — but a machine-readable format would not make you guess which half is data.
F-DT · Black: summary-panel cell 244607.89 = sum of its 271 kept rows, 244,607.89 t.F-DT · Blue: summary-panel cell 44344.33 = sum of its 154 kept rows, 44,344.33 t.F-EDT · Black: summary-panel cell 78320.78 = sum of its 209 kept rows, 78,320.78 t.Studio-F-WLA · Green: summary-panel cell 841.45 = sum of its 62 kept rows, 841.45 t.Step two · names
Facilities are reported as free text. The same physical building arrives under five spellings; some strings name no findable facility at all.
The funnel: 197 distinct raw spellings → 120 after case and whitespace → 89 normalized destinations → 56 canonical facilities. A residue never resolves: 46,859 tons (0.97%) stays unknown.
Matching names to real facilities is where the next two problems were hiding.
Sun Valley Recycling Park (546 rows, 295,414.46 t), Sun Valley Paper Stock MRF and TS (128 rows, 39,044.93 t), Sun Valley Recycle Park (72 rows, 2,705.03 t), WM - Sun Valley (1 rows, 346.70 t), WM Sun Valley Recycling Park (1 rows, 10.60 t) → sun valley mrf; family total 337,521.72 t.Frank R. Bowerman Landfill (310 rows, 189,290.97 t), Frank R Bowerman (120 rows, 135,694.94 t), Frank G Bowerman (20 rows, 26,606.37 t), Frank Bowerman (26 rows, 2,888.51 t), Frank Bowerman Landfill (2 rows, 73.60 t) → frank r bowerman landfill; family total 354,554.39 t.EL SOBRANTE LANDFILL (106 rows, 39,529.22 t), El Sobrante Landfill/ end use markets (1 rows, 270.40 t), El Sobrante and Chiquita Canyon (59 rows, 42,164.57 t) → el sobrante landfill; family total 81,964.19 t.Southeast Resource Recovery Facility (SERRF) (205 rows, 126,972.35 t), SERRF (2 rows, 2,896.28 t), Southeast Resource Recovery Facility (1 rows, 1,553.00 t) → southeast resource recovery facility; family total 131,421.63 t.Puente Hills Material Recovery Facility (215 rows, 48,491.16 t), Puente Hills Materials Recovery Facility (335 rows, 25,914.44 t), Puente Hills MRF (37 rows, 3,953.39 t), PHMRF (3 rows, 286.51 t) → puente hills mrf; family total 78,645.50 t.The Orex (66 rows, 37,276.57 t), OREX (1 rows, 48.10 t) no findable facility — stays unknown; family total 37,324.67 t.Case study 1 · the mis-merge
For most of this project’s life, 319,202.70 tons (216 report lines) recorded at a Republic transfer station in Gardena were filed under the name of an Athens compost facility in Victorville — a free-text synonym merge, made in this project’s own pipeline, that state facility records (SWIS) contradicted. Another 3,703.76 t of American Reclamation’s rode the same canonical name.
We caught it by cross-checking every name merge against SWIS — verdicts on the 16 unverified merges: 4 confirmed, 8 likely, 1 not found, 3 contradicted — and reversed the merge on July 4. Pre-fix, 365,071.03 t (7.56%) sat under SWIS-contradicted names.
The diversion math was unaffected — facility types were locked before names were merged — but the audit would have named the wrong facility. A required facility ID on each report line would have made this error impossible to write and trivial to catch. It was a naming artifact, not misconduct — by anyone.
Case study 2 · the ‘and’
59 report lines name two different landfills in one cell — el sobrante and chiquita canyon — seventy miles apart, different operators. The reports never say how much went to each.
This project’s legacy pipeline silently gave all 42,164.57 tons to one site. The audit now splits it 5.00% / 95.00% in proportion to each site’s unambiguous tonnage (39,799.62 t vs 755,724.97 t), keeping the original string as provenance; the file grows 10,259 → 10,318 rows. Our split is a documented policy, not knowledge.
One row per facility would have made this a non-event.
Case study 3 · the coin-flip
The reverse problem: one canonical name, sun valley mrf, was quietly holding two separately permitted facilities — 748 rows / 337,521.72 t, splittable 298,476.79 t (WM Sun Valley Recycling Park) vs 39,044.93 t (Sun Valley Paper Stock MRF & TS). No load ever arrived under the literal name. With the mis-merge included, 702,592.75 t (14.55%) sat under conflated or contradicted names pre-fix.
And whether a facility with “MRF and TS” in its state-registry name counts as diversion is a typing judgment worth +5.31 to +6.99 points of the headline rate. Two such facilities are typed oppositely — the sun-valley buckets are typed transfer (not diverted) while athens sun valley mrf ts is typed mrf (diverted) — a judgment that lives in a config file, inherited from the original curated mapping, not in any regulation.
The blind spot
To check the transfer wedge we used the state’s own facility database, RDRS. Of 1,072,909 transfer tons, 941,811 t (87.78%) matched. It corroborated the black-bin story almost perfectly: 666,440.50 t at est. 98.88% → landfill.
But for the blue and green share — 275,371 tons — RDRS structurally cannot answer:
“…recycling and composting inflows are never reported, so RDRS does not contain any such information”— CalRecycle’s ReadMe accompanying its PRA response; recycling outflows withheld for confidentiality
So every recycling number we can compute is a ceiling read off disposal records, not a measurement — including the matched-transfer est. 98.68% (≈929,386 t) and the sorting-facility figure in the companion piece (489,226 t → est. 458,018 t = 93.62%, a disposal-scoped ceiling, shown as one). The band on this stage never settles — both readings are drawn, and the records permit no better.
The green bin’s paperwork
Even the good news is unaudited. LA’s commercial organics stream is 227,976 tons. Material that reaches a compost facility — 77,156.98 tons across all streams (1.60% of everything) — drops off every ledger: no residual reporting, no outbound check, in this data.
The state’s public organics metric (Report 9) measures where trucks went within ten days — not what was composted: Bradley/WM Sun Valley reports routing 90.06%, Athens Sun Valley 69.13%, Crown mixed-waste organics 64.78% — and by Report 9’s own caveat, a rate is a routing claim, not a performance adjudication.
And two public datasets disagree about one facility’s organics by roughly 2×: LA County shows 53,735.3 t outbound food waste at Puente Hills; Report 9 shows 25,538.8 t of source-separated organics. Different measures, never reconciled — no contradiction asserted.
The sum
None of these defects was fraud. Each was a reporting-design choice. Their sum is that the headline diversion number depends on definitions and typing judgments no regulation specifies: the legacy definition says 41.665%; the defensible answer is 18.476% – 24.054% — and even the range leans on a database designed not to see recycling. The most stable bucket: 58.34% (2,816,965 t) went straight to a landfill — a figure that moves by well under a point across every judgment this piece names.
Where independent systems can check each other, they agree: LA County and RDRS match Puente Hills disposal to 15.4 t (0.002%), and the summary pivot reconciled to the cent. Reconciliation works when the data supports it.
Small print: the export even duplicates honestly — 93 rows in 45 exact-duplicate groups (547.8 t excess), 44 of 45 groups already present in RecycLA’s export as received; headline effect 0.005 points. The largest, as filed:
row 9,797 12/1/23 · F-WLA · Green · Mixed Organics
Downey Area Recycling and Transfer Facility (DART) → Crown Recycling Services · 486.64 t
row 9,798 12/1/23 · F-WLA · Green · Mixed Organics
Downey Area Recycling and Transfer Facility (DART) → Crown Recycling Services · 486.64 t
byte-identical in the export as received (group 30, the largest of the 45 pairs)
A conditioned bracket, computed in the audit on the pre-July-5 base: taking the disposal-stream reading of the matched wedge at face value moves D2 only +0.14 to +0.26 pp (→18.60–18.72%); the favorable blue/green reading tops out at ~24.3–24.4%; assuming every unmatched ton diverted, 27.1%.
The pivot
Each defect you just crossed maps to an auditable reporting requirement — venue-labeled, State or City, each with a test for what compliance looks like. Not “haulers should be more transparent”; a rule a validator script can check.
Where an ask partially exists already — the SWIS registry is published; SB 1383 reporting exists — the table says so and names the gap.
the full bill of particulars follows — embedded as data (#defect-data) and rendered belowThe bill of particulars
Eight observed defects, what each cost the audit, the requirement that kills it, the venue, and the compliance test. Rendered from the embedded #defect-data JSON; reconciled at load and by tests/test_methods_numbers.py against the design spec’s table.
| # | Defect (observed, cited) | Cost to this audit | Recommendation (auditable requirement) | Venue | Compliance test |
|---|---|---|---|---|---|
| R1 | Reports are a formatted export: embedded newlines, a 10,259-row unlabeled summary-pivot panel, 44/45 duplicate groups present in the export as received (row_reconciliation.md, duplicate_adjudication.md) | Weeks of parse/reconcile work before analysis could start; a "how many rows is this file" question with four defensible answers | Row-level, machine-readable tonnage reporting (defined schema, one load-aggregate per row, no summary rows, unique row IDs) filed to LASAN; the human-readable report becomes a rendering, not the record | City (franchise contract / LASAN reporting spec) | A validator script accepts or rejects each monthly filing; rejected filings are re-filed |
| R2 | Destination facilities are free text: 197 raw spellings for 56 real facilities; 46,859 t unresolvable (§5 names funnel) | An entire synonym-mapping config whose judgments (69 entries) carried no rationale and had to be forensically reconstructed and SWIS-audited | SWIS ID required on every report line naming a destination facility; free-text names allowed only as a display field | City (contract) + State (CalRecycle publishes the authoritative SWIS lookup; already exists) | Filing validator rejects rows with no valid SWIS ID; % rows with valid ID = 100 |
| R3 | Synonym merging mis-filed 319,202.70 t under the wrong facility (american organics ↔ Gardena, SWIS-contradicted, reversed 2026-07-04); 365,071 t (7.56%) carried contradicted names (contradicted_merges_impact.md) | The audit's largest single correction; found only by cross-checking every merge against SWIS | Same as R2 — standardized facility identifiers make the error class unwritable; interim: LASAN publishes its own facility crosswalk with each data release | City; State for the registry | Zero tonnage attributable to a name that contradicts the row's SWIS ID |
| R4 | One cell naming two facilities: el sobrante and chiquita canyon, 59 rows / 42,164.57 t, resolved only by a documented proportional-split policy (methodology.md owner decision 1) | An ambiguity the source created and only the source could truly resolve; our split is a policy, not knowledge | One destination facility per report line; multi-facility loads filed as multiple rows with actual per-facility tonnage | City (contract reporting spec) | Validator rejects rows whose facility field parses to >1 SWIS ID |
| R5 | Diversion treatment hangs on unregulated typing judgments: two "MRF and TS" facilities typed oppositely, a +5.3–7.0 pp headline swing living in a config file (methodology.md §5.2) | The single largest open lever on the headline; unresolvable from the data alone | Facility type / diversion treatment derives from the state registry's activity classification, not the reporter's or analyst's judgment; where a facility is dual-activity, the flow, not the facility, carries the treatment (see R7) | State (CalRecycle classification) + City (adopt it in rate computation) | Recomputing the City's rate from registry types alone reproduces the published rate |
| R6 | RDRS is disposal-only by design: "recycling and composting inflows are never reported"; recycling outflows withheld for confidentiality (CalRecycle PRA ReadMe) | Every recycling estimate is a ceiling read off disposal records — the 93.6%/98.7% figures can never become point estimates under current law; 275,370.74 t is structurally indeterminate | Require recycling- and composting-stream reporting to RDRS (inflows and outflows), with confidentiality handled by aggregation rather than omission | State (Legislature / CalRecycle regulation) | For matched facilities, inflow = Σ outflows across all streams; the residual-with-two-readings class disappears |
| R7 | No load-level tracing: the records show a first stop and sometimes an end; 1,072,909 t (22.2%) dead-ends at transfer stations; the audit's transfer-fate work is a facility-level estimate, never row tracing (transfer_fate_analysis.md §7.1) | Six ceilings and brackets where one number should be; the D1→D2 ~23-point collapse is mostly this wedge | End-fate reporting for franchise tonnage: each load-aggregate reports first destination and final disposition facility (both as SWIS IDs), with transfer/processing facilities obligated to report onward allocation of franchise tonnage | City (contract) for the hauler leg; State for the facility onward leg | The "transfer — endpoint unconfirmed" bucket computes to ~0% of tonnage |
| R8 | Compost outbound unchecked: compost-typed tonnage (77,156.98 t) drops off every ledger; Report 9 measures 10-day routing, not composting; two public datasets differ ~2× on one facility's organics (sb1383_recovery_rates.md, methodology.md §5.2) | "Reached a compost facility" is the best the audit can certify — it cannot say composted | Residual and outbound-product reporting for organics processors (tons in, product out, residual to disposal), published per facility; reconcile Report 9 and county ledgers under one definition | State (CalRecycle / SB 1383 reporting) | Per-facility organics mass balance closes within a stated tolerance |
Five sentences · 1 of 5
One sentence in a reporting spec. It retires the format archaeology (⌗), the name cloud (✎), the mis-merge (⇄), and the two-landfills string (⎂) — the entire naming class of defect becomes unwritable.
kills R1–R4 · venue: City (contract / LASAN spec); SWIS registry already existsFive sentences · 2 of 5
The seven-point coin-flip (◐) stops being a config-file judgment. Recomputing the City’s rate from registry types alone would reproduce the published rate — that’s the test.
kills R5 · venue: State classification, adopted by the CityFive sentences · 3 of 5
The blind spot (◪) closes: the ceiling readings become measurements, and the 275,371 indeterminate tons get a fate. Confidentiality is handled by aggregation, not omission.
kills R6 · venue: State (Legislature / CalRecycle regulation)Five sentences · 4 of 5
The second hop stops going silent (⊣): the 22.22% transfer wedge — the largest single reason the legacy number collapsed — computes to ~0% “endpoint unconfirmed.”
kills R7 · venue: City (contract) for the hauler leg; State for the facility legFive sentences · 5 of 5
“Reached a compost facility” becomes “was composted, with a mass balance” (▢) — and Report 9 and the county ledgers reconcile under one definition.
kills R8 · venue: State (CalRecycle / SB 1383 reporting)The finale
Five sentences, and the swamp this piece just crossed — parse, ledger, names, types, cross-check — compresses to a single step: read the answer out of the records.
We followed what the records show. These five sentences are what it would take for the records to simply answer.
The findings live in the companion explainer; the full audited record — every hauler, facility, and month, every cross-check shown — lives in the dashboard. The methodology document walks every decision made here.
Verify our work: the repository’s docs/methodology.md states every decision, and every number on this page regenerates from a fresh clone.