About this tool
Hourly life-cycle emission factors for US balancing authorities, built from EIA-930 generation data and the EPA/NETL US Electricity Baseline. This page states how the numbers are produced, what they assume, how they were checked, and where they come from — so a reader can judge whether they are fit for a given purpose rather than taking them on trust.
Data freshness
Newest hour available: 3645.2 h behind at worst across covered balancing authorities.
Ingest runs in the last 24 h: 24 · last run 2026-09-01 03:00 UTC (cron, ok)
The schedule is hourly. If the run count is 1, the platform is executing it daily — EIA-930 itself also publishes with a lag of several hours, so some staleness is expected even when the schedule is healthy.
Methodology
Each hour, EIA-930 reports generation by fuel type for a balancing authority. Every fuel is multiplied by a life-cycle emission factor for that fuel in that balancing authority, and the results are summed and divided by total generation. The output is a busbar emission factor in kg CO₂e per MWh.
The per-fuel factors are not generic. They come from the EPA/NETL US Electricity Baseline (eLCI), which is resolved to individual balancing authorities, so gas in ERCOT and gas in ISO-NE carry different burdens. They are cradle-to-gate: fuel extraction, processing and transport, plus plant construction, not only combustion. Impacts are computed with a vendored FLCAC solver under TRACI 2.2 / GWP-100.
What a spike in intensity is, and what it is not
Every factor here is a ratio — emissions divided by energy — so it is worth being explicit about what moves it. For each hour the generation of every fuel is multiplied by that fuel’s life-cycle factor, summed, and divided by the generation those factors were applied to. The result is a generation-weighted average of the fuel factors. It is therefore a property of the mix, not of the size of the hour: if a region generated half as much of everything, in the same proportions, the factor would not move at all.
This matters because a reasonable first suspicion — that intensity spikes when generation falls, so the ratio is an artefact of a small denominator — is not what these data do. Across 505,895 balancing-authority hours the correlation between energy and intensity is +0.05, which is no relationship at all. Within a day the factor tracks the fossil share almost exactly, and not the load: for CISO at 03:00 it is 271 kg CO₂e/MWh on 19,652 MWh and 50.6% fossil, at 12:00 it is 133 on more energy (24,750 MWh) at 22.1% fossil, and at 18:00 — the highest-generation hour of the day at 35,450 MWh — it is 174 at 29.8% fossil. Nor do the extremes live in the small hours: hours under 100 MWh varyless (sd ≈ 118) than hours over 1,000 MWh (sd ≈ 226).
An hour with no generation cannot produce a divide-by-zero: the factor is computed through a null-guarded division, so all 22,085 zero-energy hours in the archive carry no factor rather than an infinity, and they are excluded from every plot and average rather than counted as zero. A high evening factor is a real statement about which plants were running, not an arithmetic artefact — but because it is still a ratio, the energy behind it is recorded and plotted beside it on the changes page, so a factor is never read without the quantity it was taken over.
Storage
Batteries and pumped storage are handled with a served-basis, emission-conserving allocation. Discharged energy carries the intensity of the mix that charged it, divided by round-trip efficiency; the charging energy is removed from the hour it was drawn so nothing is counted twice. Without this, discharge is given a fossil-like “other” emission factor and evening emission factors are materially overstated — for CISO, hour 21 falls from 436 to 237 kg CO₂e/MWh once the allocation is applied. Total emissions over the window are conserved to +0.06%.
Accounting boundaries
The same grid yields different, equally correct numbers depending on the question. The map exposes seven: the hourly generation basis computed here, and six annual framings published by eLCI — generation, consumption (adds imports), consumption at user (adds transmission and distribution losses), and residual variants of each (removes contractually claimed generation). Switching framing changes what the number means, not merely how it is presented, so each is labelled with its basis wherever it appears.
Assumptions
- Attributional, average, balancing-authority scale. These are not marginal factors and not supplier- or contract-specific. A customer buying hydro from a public power authority inside a balancing authority is not represented by that authority’s average.
- Behind-the-meter solar is invisible. EIA-930 reports grid-scale generation only. NYISO reports literally zero solar while eLCI assigns it 1.8%, because New York’s solar is overwhelmingly distributed. Emission factors for such regions are biased high, and the method cannot correct it.
- Round-trip efficiency is a documented default (0.85), not measured per cycle. ERCOT’s observed round-trip is closer to 0.80, so its discharge factor is understated by roughly 6%.
- Hourly consumption is normalised over inbound energy, not over demand. A balancing authority’s shares are computed against its own generation plus its imports. That quantity cannot be negative and its shares always sum to one, so a balancing authority that fails to close — 2.51% of hours do — still yields valid arithmetic. Imbalance changes how much confidence a figure deserves, never whether it is well formed. It also means the denominator is energy entering the region, which is not the same as the energy its customers consumed.
- Energy arriving from an endpoint with no emission factor is never given a neighbour’s mix instead. Six of the 71 tie endpoints have no emission factor from any source. That energy is excluded from the numerator and from the renormalised denominator, and the share it accounts for is published for every hour as
unpriced_share. The result states what the figure covers rather than filling the gap with a substitute: the factor describes only the inbound energy that has a factor, so reading it as covering all consumption overstates its reach by exactly that share. It is above zero in 9.8% of balancing-authority hours and reaches 50% at worst — half the inbound energy with no factor available — so this is not a rounding concern. - An hour whose ties were partly unusable still gets a factor, and the factor says so. 1.43% of tie-hours are contradictory or implausible and are excluded from tracing. Rather than dropping the affected balancing-authority hours entirely, each hour carries
excluded_share— the volume of unusable ties relative to inbound energy. Non-zero means the mix was computed over less of the network than it appears to be. Suppressing those hours would have been the more conservative-looking choice, but it would remove exactly the hours where the grid was hardest to measure, leaving a record that looks cleaner than the data is. - eLCI factors are an annual vintage. They do not track recent structural change. New York’s grid now runs 54.1% gas against eLCI’s 41.7%, following nuclear retirements after the release vintage.
- Not every balancing authority has hourly data, for three different reasons. Of the 65 territories on the map, most carry hourly factors, but a handful do not and the causes are not the same:
- EIA publishes none. PowerSouth (AEC), Electric Energy Inc (EEI), Griffith Energy (GRIF) and New Smyrna Beach (NSB) appear in EIA’s respondent list and report demand, but have filed no generation-by-fuel data in two years. They are single-plant or small municipal operators that mostly buy power and settle through interchange, so there is little own-generation to report. The series does not exist; nothing here is missing it.
- Reporting stopped. New Harquahala (HGMA) filed 7,349 hours of natural-gas generation and then stopped in June 2025. It remains in the request set, so it will reappear if reporting resumes.
- No life-cycle factors. eLCI does not publish generation processes for every balancing authority. City of Homestead (HST) has current EIA data but no BA-specific eLCI processes, so it is admitted on US national fallback factors— reasonable there because it is essentially single-fuel, but the level is not BA-resolved and the panel says so.
- Fallback factors are more widespread than the headline suggests. A balancing authority is not simply “resolved” or “not”: eLCI may publish processes for some of its fuels and not others, in which case the remainder falls back to national averages. Roughly half the covered set is mixed on this measure. The detail panel states the share whenever it is below 100%, because a partly-national factor and a fully BA-resolved one otherwise look identical.
The reason is sometimes more interesting than the number. PacifiCorp West sits at 57% because eLCI’s generation mix for it contains no fossil fuel at all — hydro 58.5%, wind 22.5%, solar 15.9%, biomass 3.1% — while EIA-930 reports it at 38.9% natural gas and eGRID measures direct emissions that only exist if something burns. eLCI publishes no gas process to apply to the remainder. It does publish a combined-cycle gas construction process for PacifiCorp West, so the release models the building of a fleet whose generation it does not model. - Boundaries are approximate. eGRID subregion polygons are 2024 ZIP codes dissolved by subregion, not service territories. Balancing-authority territories overlap — 143 polygon pairs — so a location can sit in several at once; the map resolves a click to the smallest containing territory.
Network balance
Consumption framings rest on a flow network assembled from EIA’s directed interchange reports. That network does not close, and no amount of care will make it: generation, each neighbour’s generation and every tie are independent measurements. Requiring balance would mean discarding most hours or inventing a correction, so the method is built to tolerate imbalance and the imbalance is published.
A balancing authority’s mix shares are normalised over inbound energy — its own generation plus its imports. Inbound cannot be negative and its shares always sum to one, whatever the exports do. So a deficit changes how much confidence a factor deserves, never whether the arithmetic is valid.
- Hours that do not balance
- 2.5%
- of modelled balancing-authority hours export more than their own generation plus imports can account for
- Energy that does not balance
- 0.08%
- 408,615 MWh — the same gap measured in energy rather than in hours
- Genuinely unattributable
- 801 GWh
- arriving from the 6 endpoints no source gives an emission factor for, out of 26,448 GWh crossing unmodelled endpoints in total
The first two numbers are the same gap counted two ways, and the difference between them is the point: hours that fail to balance are common, but the energy involved is not. A node is typically short by a little, often — not by a lot, ever. Reporting only the hour count would overstate the problem by a factor of thirty.
Network-wide imbalance is exactly zero: the reconciliation rule is conserving by construction, so whatever leaves one node arrives at the other. The residual is entirely a per-node question. Measured over 615,001 balancing-authority hours, of which 87,954 have an endpoint whose generation is never ingested — a statement about this pipeline’s coverage rather than about the grid.
| BA | Deficit MWh | % of exports | Hours |
|---|---|---|---|
| GWA | 168,495 | 24.9% | 3,917 |
| TIDC | 126,353 | 6.4% | 565 |
| SPA | 34,081 | 0.8% | 731 |
| SEPA | 26,526 | 1.1% | 2,692 |
| GRID | 12,683 | 0.1% | 3,949 |
| DEAA | 11,238 | 0.3% | 64 |
| WALC | 9,608 | 0.1% | 33 |
| SEC | 6,043 | 0% | 27 |
What sits at the end of each tie
60 of 71 endpoint codes are ingested hourly with their own generation. 5 more take a factor from an eLCI annual generation mix — these were a crosswalk gap rather than a data gap, published by eLCI under entity names never mapped to their EIA codes. The remaining 6 have no emission factor from any source, so energy arriving from them is reported as unattributable rather than quietly assigned a neighbour’s mix.
| Code | Factor from | Basis |
|---|---|---|
| BCHA | British Columbia Hydro and Power Authority | eLCI publishes a generation mix for BC Hydro (47.1 kg CO2e/MWh). Exact entity identity. |
| HQT | Hydro-Quebec TransEnergie | eLCI publishes a generation mix for Hydro-Quebec TransEnergie (8.9). Exact entity identity. NOT "New Harquahala Generating Company", which a substring search also returns. |
| IESO | Ontario IESO | eLCI publishes a generation mix for Ontario IESO (88.4). Exact entity identity. |
| MHEB | Manitoba Hydro | eLCI publishes a generation mix for Manitoba Hydro (14.3). Exact entity identity. Material: MHEB exports ~2,161 MWh/hour into MISO and imports nothing, so it is a pure source node. |
| NBSO | New Brunswick System Operator | eLCI publishes a generation mix for the New Brunswick System Operator (213.2). Exact entity identity. |
| AESO | no factor | Alberta Electric System Operator. eLCI publishes no mix for Alberta. |
| BHBA | no factor | Black Hills Power sub-area. No eLCI entity. |
| CEN | no factor | CFE control area, Baja California. No eLCI entity. Explicitly NOT Public Service Company of New Mexico, which a name search returns. |
| SIKE | no factor | City of Sikeston, Missouri. No eLCI entity. |
| SPC | no factor | Saskatchewan Power Corporation. eLCI publishes no mix for Saskatchewan. |
| SWPW | no factor | Southwest Power Pool sub-area reported separately from SWPP. No eLCI entity of its own; assigning SWPP's mix would assume the sub-area matches the pool, which is untested. |
Every mapping above is pinned by inspection. Searching eLCI’s entity names for the six codes with no factor returned two confident false positives — CEN matched “Public Service Company of New Mexico” on the string “Mexico”, and SWPW matched “Southwest Power Pool” on “Power Pool”. Both would have fabricated a factor from a string coincidence, so name similarity is never used to establish identity anywhere in this tool.
Following imports past the first hop
Two accountings are published for every hour, not one. First-order gives an import the emission factor of the region that exported it and stops there — this is what eLCI itself does, and reproducing its published consumption mix from its own weights confirms the method exactly, 60 of 60. Recursive follows the energy back to where it was generated: power reaching A through B from C takes the factor of what C generated, solved as a linear system rather than iterated.
| BA | First-order | Recursive | Gap, hourly | Gap, annual |
|---|---|---|---|---|
| TPWR | 20.6 | 53.3 | +158.1% | +18.6% |
| DOPD | 3.0 | 6.2 | +105.3% | 0.0% |
| SCL | 21.7 | 41.0 | +88.9% | +18.7% |
| PSEI | 82.7 | 125.9 | +52.2% | +4.6% |
| CHPD | 2.8 | 3.7 | +29.5% | 0.0% |
| PGE | 164.5 | 200.1 | +21.6% | +4.9% |
| GCPD | 30.9 | 24.3 | -21.3% | -11.3% |
| SEPA | 214.5 | 188.8 | -12.0% | -4.6% |
The distribution is heavy-tailed rather than uniform: the median balancing authority differs by 0.47% and 35 of 60 differ by less than 1%. Multi-hop tracing is close to irrelevant for a large, self-sufficient region and decisive for a small import-dependent one.
The last two columns are the finding. Annual weights blend the hours a hydro utility runs on its own water into the hours it buys fossil power, and the correction largely vanishes in the average — for Tacoma Power by a factor of more than eight. A practitioner using a published annual consumption mix for an import-dependent region is holding a number whose temporal aggregation has removed most of the effect it exists to capture.
Verification methods
The factors are checked against independent anchors rather than asserted. Two of those checks produce numbers that look contradictory for the same balancing authority — a 0.0% agreement with eLCI and a +29.6% divergence from it. They are not in conflict: they hold different things constant. The diagram traces both for NYISO.
All balancing authorities
61 of 61 pass check 1 within 0.05%, so the factors reproduce eLCI’s own published figure across the fleet, not only for the worked example. Check 2 has no pass/fail — it measures how far each grid has moved since eLCI’s vintage. Check 3 compares against a 2023 measurement, so it mixes the boundary difference with that same vintage drift; the final column removes the drift by comparing the vintage-matched reconstruction instead, which is the column to read when judging whether the boundary logic holds.
A negative check 3 is not a failed factor. A life-cycle result must exceed a combustion-only one, so a negative looks like a defect. For every balancing authority where it occurs, eGRID’s rate turns out to exceed what that BA’s observed fuel mix could physically emit even at worst-case combustion factors — 15 BAs fail that ceiling test, and all 10 negatives are among them. Southwestern Power Administration is the clearest: 100.0% hydro across 3,989 GWh with no combustion in any hour, and an eGRID direct rate of 236.7. The two datasets are describing different sets of plants under one code, so the comparison is not like-for-like. Recorded as egrid-attribution-mismatch and raised with EPA.
| BA | recon | eLCI pub. | 1 · factors | observed | 2 · grid | eGRID | 3 · magnitude | 3 · vintage-matched |
|---|---|---|---|---|---|---|---|---|
| AECI | 635.2 | 635.2 | +0.0% | 679.2 | +6.9% | 586.1 | +15.9% | +8.4% |
| AVA | 276.0 | 276.0 | −0.0% | 310.9 | +12.6% | 164.9 | +88.5% | +67.4% |
| AVRN | 51.5 | 51.5 | −0.0% | 277.9 | +439.7% | 167.7 | +65.7% | −69.3% |
| AZPS | 754.3 | 754.3 | −0.0% | 513.0 | −32.0% | 661.1 | −22.4% | +14.1% |
| BANC | 227.8 | 227.8 | +0.0% | 281.9 | +23.7% | 174.2 | +61.8% | +30.8% |
| BPAT | 118.4 | 118.4 | +0.0% | 24.5 | −79.3% | 96.9 | −74.7% | +22.1% |
| CHPD | 1.9 | 1.9 | +0.0% | 2.0 | +2.4% | 0.0 * | — | — |
| CISO | 209.5 | 209.5 | −0.0% | 190.6 | −9.0% | 168.1 | +13.4% | +24.6% |
| CPLE | 261.6 | 261.6 | +0.0% | 468.8 | +79.2% | 219.3 | +113.8% | +19.3% |
| CPLW | 47.0 | 47.0 | +0.0% | 662.4 | +1309.7% | 0.0 * | — | — |
| DEAA | 508.7 | 508.7 | −0.0% | 508.7 | +0.0% | 396.4 | +28.3% | +28.3% |
| DOPD | 0.7 | 0.7 | +0.0% | 0.7 | +0.0% | 0.0 * | — | — |
| DUK | 285.4 | 285.4 | −0.0% | 482.9 | +69.2% | 220.6 | +118.9% | +29.4% |
| EPE | 556.8 | 556.8 | −0.0% | 469.8 | −15.6% | 458.9 | +2.4% | +21.3% |
| ERCO | 384.2 | 384.2 | −0.0% | 352.3 | −8.3% | 334.2 | +5.4% | +15.0% |
| FMPP | 593.8 | 593.8 | +0.0% | 580.7 | −2.2% | 524.5 | +10.7% | +13.2% |
| FPC | 517.8 | 517.8 | +0.0% | 514.3 | −0.7% | 441.3 | +16.5% | +17.3% |
| FPL | 329.9 | 329.9 | +0.0% | 306.0 | −7.2% | 271.5 | +12.7% | +21.5% |
| GCPD | 3.7 | 3.7 | −0.0% | 3.7 | +0.0% | 0.0 * | — | — |
| GRID | 483.8 | 483.8 | +0.0% | 470.8 | −2.7% | 399.1 | +18.0% | +21.2% |
| GRIF | 494.9 | 494.9 | +0.0% | — | — | 391.0 | — | +26.6% |
| GVL | 821.7 | 821.7 | +0.0% | 822.8 | +0.1% | 719.0 | +14.4% | +14.3% |
| GWA | 21.2 | 21.2 | −0.0% | 21.2 | +0.0% | 0.0 * | — | — |
| HGMA | 448.9 | 448.9 | +0.0% | — | — | 378.1 | — | +18.7% |
| IID | 213.5 | 213.5 | +0.0% | 152.0 | −28.8% | 114.0 | +33.4% | +87.3% |
| IPCO | 138.4 | 138.4 | +0.0% | 170.9 | +23.4% | 102.2 | +67.2% | +35.4% |
| ISNE | 321.9 | 321.9 | +0.0% | 371.7 | +15.5% | 247.3 | +50.3% | +30.2% |
| JEA | 663.8 | 663.8 | −0.0% | 736.9 | +11.0% | 531.5 | +38.6% | +24.9% |
| LDWP | 561.1 | 561.1 | +0.0% | 371.4 | −33.8% | 461.5 | −19.5% | +21.6% |
| LGEE | 970.7 | 970.7 | +0.0% | 946.7 | −2.5% | 865.5 | +9.4% | +12.2% |
| MISO | 533.8 | 533.8 | +0.0% | 491.4 | −7.9% | 447.9 | +9.7% | +19.2% |
| NEVP | 382.9 | 382.9 | +0.0% | 474.4 | +23.9% | 320.5 | +48.0% | +19.5% |
| NWMT | 756.5 | 756.5 | +0.0% | 547.5 | −27.6% | 723.4 | −24.3% | +4.6% |
| NYIS | 238.3 | 238.3 | +0.0% | 312.3 | +31.0% | 218.0 | +43.2% | +9.3% |
| PACE | 714.4 | 714.4 | +0.0% | 591.4 | −17.2% | 643.6 | −8.1% | +11.0% |
| PACW | 62.3 | 62.3 | −0.0% | 253.3 | +306.8% | 140.2 | +80.7% | −55.6% |
| PGE | 401.9 | 401.9 | +0.0% | 412.6 | +2.7% | 361.1 | +14.3% | +11.3% |
| PJM | 385.8 | 385.8 | +0.0% | 423.5 | +9.8% | 326.3 | +29.8% | +18.2% |
| PNM | 224.9 | 224.9 | −0.0% | 252.8 | +12.4% | 179.0 | +41.2% | +25.6% |
| PSCO | 416.2 | 416.2 | +0.0% | 385.9 | −7.3% | 365.7 | +5.5% | +13.8% |
| PSEI | 457.6 | 457.6 | −0.0% | 312.1 | −31.8% | 291.5 | +7.1% | +57.0% |
| SC | 906.0 | 906.0 | +0.0% | 908.0 | +0.2% | 766.7 | +18.4% | +18.2% |
| SCEG | 412.5 | 412.5 | +0.0% | 427.3 | +3.6% | 339.5 | +25.8% | +21.5% |
| SCL | 1.6 | 1.6 | +0.0% | 1.6 | +0.0% | 0.4 * | +298.8% | +298.9% |
| SEC | 655.7 | 655.7 | +0.0% | 638.1 | −2.7% | 550.5 | +15.9% | +19.1% |
| SEPA | 1.6 | 1.6 | −0.0% | 0.0 | −100.0% | 0.0 * | −100.0% | +4267.1% |
| SOCO | 462.3 | 462.3 | −0.0% | 450.4 | −2.6% | 384.0 | +17.3% | +20.4% |
| SPA | 278.9 | 278.9 | +0.0% | 61.8 | −77.8% | 236.7 | −73.9% | +17.8% |
| SRP | 275.8 | 275.8 | −0.0% | 254.9 | −7.6% | 250.7 | +1.7% | +10.0% |
| SWPP | 438.8 | 438.8 | +0.0% | 445.7 | +1.6% | 397.5 | +12.1% | +10.4% |
| TAL | 468.6 | 468.6 | −0.0% | 468.0 | −0.1% | 384.4 | +21.7% | +21.9% |
| TEC | 451.4 | 451.4 | +0.0% | 400.7 | −11.2% | 388.9 | +3.0% | +16.1% |
| TEPC | 740.6 | 740.6 | +0.0% | 569.0 | −23.2% | 740.7 | −23.2% | −0.0% |
| TIDC | 431.1 | 431.1 | −0.0% | 474.3 | +10.0% | 350.6 | +35.3% | +22.9% |
| TPWR | 2.0 | 2.0 | −0.0% | 2.0 | +0.0% | 2.7 * | −24.3% | −24.3% |
| TVA | 332.4 | 332.4 | −0.0% | 357.0 | +7.4% | 292.1 | +22.2% | +13.8% |
| WACM | 881.4 | 881.4 | −0.0% | 697.5 | −20.9% | 853.8 | −18.3% | +3.2% |
| WALC | 280.9 | 280.9 | −0.0% | 265.1 | −5.6% | 218.6 | +21.3% | +28.5% |
| WAUW | 22.7 | 22.7 | −0.0% | 22.0 | −3.3% | 0.0 * | — | — |
| WWA | 13.8 | 13.8 | −0.0% | 13.8 | +0.0% | 0.0 * | — | — |
| YAD | 4.5 | 4.5 | +0.0% | 4.5 | +0.0% | 0.0 * | — | — |
Values in kg CO₂e/MWh. recon = our factors applied to eLCI’s own mix shares; observed = generation-weighted mean over everything ingested, matching the basis eLCI and eGRID both publish on; eGRID = eGRID2023, direct emissions only.
* 11 balancing authorities have an eGRID rate below 5 kg CO₂e/MWh — hydro-dominated federal marketers, mostly. Percentage comparisons against a near-zero denominator explode and should be read as absolute differences instead.
4 fail check 3 even vintage-matched: AVRN, PACW, TEPC, TPWR. A life-cycle figure below a combustion-only one should not happen, so these are open items rather than explained ones. Two are immaterial — TEPC, TPWR differ by under 1 kg CO₂e/MWh, which is noise at that magnitude. The others are genuine discrepancies under investigation, most likely where eLCI’s mix for the BA and the fleet eGRID measured are not describing the same set of plants.
Check 3, at the level EPA recommends
EPA is explicit that the balancing-authority rates are the wrong tool for this: “EPA recommends using the output emissions rates from the eGRID subregion level … Data for balancing authorities are included in eGRID as a reference.” Compared at the level EPA does recommend, aggregating our balancing authorities up by eGRID’s own plant-level generation shares, the check carries weight.
- Ours, life-cycle
- 408.4
- kg CO₂e/MWh across 4,322 TWh
- eGRID, direct only
- 347.6
- same generation, combustion boundary
- Difference
- +17.5%
- life-cycle above direct, as it must be — 16 of 22 subregions positive
| Subregion | Ours | eGRID direct | Difference | TWh |
|---|---|---|---|---|
| NYLI† | 312.3 | 539.5 | -42.1% | 10.1 |
| MROE | 491.4 | 637.3 | -22.9% | 25.3 |
| NYCW† | 312.3 | 392.7 | -20.5% | 35.7 |
| NWPP | 263.8 | 288.2 | -8.4% | 284 |
| RMPA | 444.5 | 472.9 | -6% | 61.8 |
| SRMW | 532.8 | 566.3 | -5.9% | 104.3 |
| RFCW | 436.3 | 415.5 | +5% | 557.6 |
| ERCT | 353.4 | 334.1 | +5.8% | 503.8 |
| RFCM | 485.6 | 442.7 | +9.7% | 95.5 |
| SPSO | 441.4 | 397.2 | +11.1% | 170.1 |
| CAMX | 216.6 | 195 | +11.1% | 207.3 |
| SRTV | 456.3 | 409.7 | +11.4% | 212.6 |
| SPNO | 445.6 | 393.6 | +13.2% | 81.6 |
| FRCC | 407.3 | 356 | +14.4% | 269 |
| MROW | 482.8 | 420.3 | +14.9% | 246.6 |
| AZNM | 369.7 | 320.3 | +15.4% | 173.2 |
| SRSO | 451.3 | 383.7 | +17.6% | 261.3 |
| SRMV | 491.3 | 336.4 | +46% | 181.7 |
| NEWE | 371.7 | 246.4 | +50.9% | 111.5 |
| RFCE | 423.5 | 271.8 | +55.8% | 306.3 |
| SRVC | 481.2 | 270.5 | +77.9% | 334.8 |
| NYUP† | 312.3 | 110.1 | +183.6% | 88.3 |
† The three New York rows are one balancing authority. NYISO spans NYUP, NYCW and NYLI, so it carries a single factor of 312.3 against subregion realities eGRID puts at 110.1, 392.7 and 539.5. No method operating at balancing-authority resolution can represent a spread like that — it is a limit of the accounting unit, not an error in the arithmetic. The remaining negatives are small (NWPP −8.4%, RMPA −6.0%, SRMW −5.9%) and consistent with a 2023 measurement being compared against a 2025–26 window on a grid that has kept getting cleaner.
The three sources are not interchangeable. eLCI supplies the factors and a figure to check them against; EIA-930 supplies the mix eLCI’s vintage cannot know; eGRID is an outside measurement on a narrower boundary, so it can confirm the result is the right size without ever agreeing exactly. Losing any one of them would leave a class of error undetectable.
- Reconstruction against eLCI’s own mix. Applying our per-fuel factors to eLCI’s published generation-mix shares reproduces its published mix emission factor exactly — 0.0% difference for CISO, PJM and NYIS. This test is independent of the sampling window, which matters because comparing a six-week summer average against an annual figure is not a like-for-like test.
- Comparison against eGRID. eGRID2023 publishes direct, operational emission rates per balancing authority. Life-cycle factors should sit above them, and do — CISO is +10% against eGRID’s direct figure, which is the expected direction and magnitude for upstream fuel and construction burdens.
- Islanded-grid control. ERCOT is essentially islanded, so its generation and consumption mixes must agree. They do, to 0.0% — a case where the framings are required to coincide, and a useful check that the consumption accounting is behaving.
- Emission conservation for storage. The storage allocation re-times emissions rather than creating or destroying them; summed over the window, delivered emissions match primary emissions to +0.06%.
- Outlier review. A hydro factor of 1702.6 kg CO₂e/MWh for MISO — higher than coal, and the largest of 42 hydro processes against a median of 9.7 — was traced to a superseded eLCI release rather than patched. Refreshing to the current release gives 35.3.
Data sources
- EIA-930 Hourly Electric Grid Monitor · data
- Hourly generation by fuel and directed interchange between balancing authorities. Ingested through the EIA API v2 with a trailing three-day re-pull, because EIA revises after publication.
- eLCI — US Electricity Baseline, Federal LCA Commons · data
- Life-cycle emission factors per fuel and balancing authority, release 1.2026-06.0, TRACI 2.2 / GWP-100. Repository Federal_LCA_Commons/US_electricity_baseline.
- eGRID2023 — US EPA · data
- Direct (combustion-only) emission rates for 2023, used as an independent magnitude check. EPA recommends the subregion level; the balancing-authority rates are reference only.
Detail on how each is used, and what it does not cover:
- Hourly generation by fuel — EIA-930
- US Energy Information Administration, Hourly Electric Grid Monitor, via the EIA API v2. Ingested hourly with a trailing three-day re-pull to absorb revisions.
- Life-cycle factors — EPA/NETL US Electricity Baseline (eLCI)
- Federal LCA Commons,
Federal_LCA_Commons/US_electricity_baseline, release 1.2026-06.0. TRACI 2.2, GWP-100, computed with a vendored FLCAC matrix solver calibrated to openLCA within ~0.05%. Chosen over raw USLCI because USLCI has no wind, solar or hydro electricity processes and is national-only. - Balancing-authority territories — HIFLD Control Areas
- A 2025-04 archived snapshot obtained from DataLumos. This dataset is no longer publicly hosted — both the original HIFLD Open entry and the EIA Atlas layer now return 404 — so it is a point-in-time archive rather than a live source, and will not reflect later boundary changes. EIA-930 codes come from the EIA API, joined to the geometry by a pinned crosswalk rather than name similarity.
- eGRID subregions and rates — EPA eGRID2023
- January 2025 mapping files for geometry and the June 2025 data revision for emission rates. Boundaries are ZIP-code-derived.
Questions for the data publishers
Some findings cannot be resolved here. Where the evidence points at the source rather than at this tool, the question is recorded with the numbers that prompted it and put to the publisher. 11 are open.
eGRID · 3
Is eGRID2024 still expected, and when?
Evidence. The detailed-data page states "Next planned release: eGRID2024 in January of 2026". The eGRID landing page, last updated 2026-07-28, still presents eGRID2023 (2023 data, released 2025-01-15, revised 2025-06-12) as current.
Why it matters. Our observation window is 2025-08 to 2026-08, so the reference measurement is two to three years stale and biases check 3 in a known direction. About half the residual subregion-level disagreement should close if the vintage explanation is right, which is testable the moment eGRID2024 lands.
Does the BPAT rate cover plants beyond those EIA-930 attributes to BPAT?
Evidence. EIA-930 reports BPAT as 75.7% hydro, 10.7% nuclear, 7.7% wind and 3.8% gas. The most a mix like that could emit directly, using worst-case combustion factors, is about 34 kg CO2e/MWh. eGRID2023 gives BPAT 96.9 -- 2.85x that ceiling. Fifteen BAs exceed their physical ceiling on the same test.
Why it matters. eGRID is our only source independent of both EIA and eLCI, so it is the check that catches errors the other two share. If its BA-level plant set differs systematically from EIA-930's, that check needs re-basing on subregions rather than balancing authorities. PARTIALLY ANSWERED by EPA's FAQ: "EPA recommends using the output emissions rates from the eGRID subregion level ... Data for balancing authorities are included in eGRID as a reference." That resolves which level to use. It does not state the BA assignment rule, which is what makes the BA-level figures misleading when joined to EIA-930.
Sikeston is a balancing authority in EIA-930 and not an eGRID BACODE. What rule assigns a plant to a BA, and how should marketing administrations be treated?
Evidence. eGRID2023 PLNT23 assigns the Sikeston coal plant (operator: City of Sikeston, Missouri) to BACODE=SPA. It contributes 1,615 of SPA's 1,617 kt CO2e, so 99.9% of the emissions attributed to Southwestern Power Administration come from one plant that EIA-930 reports as its own balancing authority, SIKE -- a code that does not appear in eGRID at all. EIA-930 reports SPA itself as 100.0% hydro across 3,989 GWh with no combustion in any hour.
Why it matters. Anyone joining eGRID BA rates to EIA-930 BA data -- a natural thing to do, since both key on the same code space -- silently combines two different plant sets. EPA's FAQ recommends the subregion level but does not say the BA level is unsafe to join, and the code overlap makes it look safe.
eLCI · 8
Does "Avangrid Renewables, LLC" denote the company's national portfolio or the AVRN balancing authority?
Evidence. eLCI's mix is WIND 82.66%, SOLAR 13.26%, GAS 4.08%. EIA-930's AVRN over 8,887 hours is WND 60.9%, NG 39.1% and SOLAR exactly 0.0% -- no solar output in any hour. The gas is one unit peaking at 554 MWh/h and running in 7,841 of 8,887 hours. AVRN has only two ties (BPAT, PACW) and net-exports 99% of what it generates.
Why it matters. A fleet cannot gain a baseload combined-cycle plant and lose its entire solar portfolio in one revision, so this looks like two different plant sets under one name. If eLCI models the company, its factor should not be joined to the EIA BA code, and our crosswalk is wrong to do so.
Is there an official mapping from eLCI entity names to EIA balancing-authority codes?
Evidence. We match by pinned inspection because name similarity is unsafe here: "SOUTHEASTERN POWER ADMINISTRATION" and "SOUTHWESTERN POWER ADMINISTRATION" score 0.97 similar and are different agencies, both real BAs. Two further false positives arose while mapping tie endpoints -- "CEN" matched "Public Service Company of New Mexico" on the string "Mexico" (CEN is a CFE control area in Baja California) and "SWPW" matched "Southwest Power Pool" on "Power Pool" (SWPW is a sub-area).
Why it matters. Every downstream join depends on this mapping, and a wrong pin silently assigns one utility's emissions to another. A published crosswalk would remove an entire class of error.
The Canadian intertie entities are published without EIA codes. Can the mapping be confirmed?
Evidence. eLCI publishes generation mixes for British Columbia Hydro and Power Authority (47.1), Hydro-Quebec TransEnergie (8.9), Ontario IESO (88.4), Manitoba Hydro (14.3) and the New Brunswick System Operator (213.2). EIA-930 reports the corresponding ties as BCHA, HQT, IESO, MHEB and NBSO. Alberta (AESO) and Saskatchewan (SPC) appear as tie endpoints with no eLCI entity.
Why it matters. MHEB alone exports ~2,161 MWh/hour into MISO and imports nothing. Without the mapping that energy is unattributable; with an unconfirmed mapping it is attributed on our judgement rather than the publisher's.
Are the published consumption mixes first-order by design -- imports priced at the exporter's GENERATION mix, with no further tracing?
Evidence. Reconstructing each consumption mix from its own declared import shares, pricing every import at the exporter's generation mix and stopping there, reproduces the published figure for 60 of 60 balancing authorities to within 0.05%. A full recursive solve over the same weights does not.
Why it matters. It determines whether a recursive flow-tracing result should be expected to agree with eLCI or to differ from it. We currently publish both and describe the difference as a method choice; confirmation would let that be stated as fact rather than inference.
Was the MISO hydro factor in release 1.2025-06.0 a known error, and is there an erratum?
Evidence. Release 1.2025-06.0 gave MISO hydro 1702.6 kg CO2e/MWh -- higher than coal, and the largest of 42 hydro processes against a median of 9.7. Release 1.2026-06.0 gives 35.3 for the same entity, and the earlier process UUIDs no longer resolve.
Why it matters. We found it by outlier review rather than by any published notice. Anyone still pinned to the earlier release is using a hydro factor roughly 48x too high with nothing signalling it.
What year or years does each entity's generation mix represent?
Evidence. Release notes give a 2016-2023 range for the baseline, but per-entity vintage is not stated. Check 2 (observed mix against published mix) is intended to measure how far a grid has moved since its vintage, and currently ranges from 0.0% to +440% across the fleet.
Why it matters. Without a per-entity vintage, a large check-2 gap cannot be separated into "the grid changed" and "the model is wrong". It is the single piece of metadata that would make that check diagnostic rather than merely descriptive.
PacifiCorp West has no fossil generation process. Is that intentional, or an omission?
Evidence. The generation-mix process for PacifiCorp West (release 1.2026-06.0) draws only on HYDRO 58.51%, WIND 22.54%, SOLAR 15.89% and BIOMASS 3.06%. There is no Electricity - GAS - PacifiCorp West process. The release nevertheless publishes "power plant construction - ngcc_const - PacifiCorp West", modelling the construction of a combined-cycle gas fleet. EIA-930 reports PACW at 38.9% natural gas over 2025-08 to 2026-08, between 18.9% and 53.0% every month, and eGRID2023 gives PACW a direct rate of 140.2 kg CO2e/MWh.
Why it matters. PACW's published generation mix (62.3) sits below eGRID's combustion-only rate, which cannot hold for one system. Any practitioner using eLCI for PacifiCorp West is pricing a fossil-free grid that neither EIA nor EPA observes.
What exactly does the residual mix subtract -- voluntary claims only, or all registry-settled certificates including RPS compliance?
Evidence. Read from the release's own process exchanges: the ISO New England residual generation mix removes 0.71pp of hydro, 0.30pp of solar, 0.27pp of wind and 0.18pp of biomass versus the generation mix -- an even ~8% haircut on each renewable category, about 1.5% of the pool. NEPOOL GIS settled, reserved or exported 39.47% of the region's 2023 certificates; its unsettled pool (73% gas, 10% oil, four nuclear certificates of 66.6M) reconstructs to 585.9-619.3 kg CO2e/MWh with the release's own per-fuel factors, against the published residual of 324.5. Same comparison for PJM (GATS registry, 2023): unsettled pool reconstructs to 467.5-468.7 kg CO2e/MWh vs eLCI residual_generation 394.0 (+19%), with 17.55% of certificates settled; the identical pricing of the full system mix lands within 4% of eLCI's generation mix. Extended to all regions with public 2023 data: New York (NYGATS publishes its residual directly: our pricing 403.5 vs eLCI 229.9, +75.5%), MISO (M-RETS claim rate: 588.2 vs 552.9, +6.4%), Texas (ERCOT REC retirements: 466.3 vs 482.5, -3.4%), California (no public WREGIS data; Green-e CAMX rate 197.0 vs 217.6, different construction). The gap tracks each pool's settled share; system-mix checks price within 2.4-4.0% wherever a registry system mix exists to check against.
Why it matters. Residual mixes exist to prevent double counting. If eLCI subtracts less than the registry settles, a consumer using eLCI's residual while others hold the settled certificates is still double counting -- by nearly a factor of two on this measurement.
Known discrepancies
63 recorded · 19 open, 9 high-severity. Everything found so far, including the items that are unresolved. An entry is closed only when it is actually fixed; findings that were explained rather than fixed stay listed, because the explanation is itself something worth checking. Nothing is removed.
- openhigh · factors · AVRNAVRN life-cycle factor below eGRID direct
Found: Vintage-matched reconstruction is 51.5 kg CO2e/MWh against eGRID2023 direct of 167.7 -- a gap of -116.2. A life-cycle figure must EXCEED a combustion-only one.
Assessment: Not explained. Most likely eLCI's mix for Avangrid Renewables and the fleet eGRID measured are not describing the same set of plants, but that is a hypothesis, not a finding.
Action: Open. Needs the eLCI process composition compared against eGRID's plant list for this BA.
- openhigh · factors · CPLWCPLW observed EF 13x its eLCI generation mix
Found: Observed hourly mean is 645.6 kg CO2e/MWh against an eLCI published generation mix of 47.0. CPLW also prices ~0.1% of its generation with BA-specific factors -- effectively all national fallback.
Assessment: A gap of this size is not vintage drift. Most likely the eLCI entity matched to CPLW does not correspond to the fleet EIA-930 reports under that code.
Action: Open. Verify the eLCI entity to EIA-930 code mapping for CPLW specifically.
- openhigh · ops · all BAsHourly cron executes once a day
Found: vercel.json schedules 0 * * * * but write clusters show a single run at 12:00 UTC daily. The map runs up to ~24h stale.
Assessment: Matches Hobby-plan cron behaviour, though PROJECT-STATE records the plan as Pro. It went unnoticed for days because nothing recorded cron runs.
Action: Run logging added (ingest_run + ingest_status). The schedule itself needs checking in the Vercel dashboard -- a billing/account matter, not code.
- openhigh · method · all consumption and residual-consumption framingseLCI consumption mix is first-order, not a network solve
Found: Reconstructing eLCI's published consumption mix from the import weights declared in its own process exchanges reproduces it EXACTLY (0.000% for NYIS, CISO, ISNE). The inputs are entirely GENERATION-mix processes, weights summing to 1.0 -- so consumption(A) = sum over B of share(A,B) x generation(B).
Assessment: eLCI prices imports at the exporter's GENERATION mix, stopping after one hop. It does NOT solve the recursive system consumption(A) = sum share(A,B) x consumption(B), which is what the standard flow-tracing literature (de Chalendar et al., PNAS 2019) does and what (I - T)^-1 computes. Power imported into B from C before flowing to A is therefore priced as if B had generated it.
Action: Open decision for Phase 2. A full network solve is more defensible but will NOT reproduce eLCI's consumption figures even given identical import weights, so the comparison against eLCI stops being a validation and becomes a methodological difference. Options: (a) implement both and publish the gap, (b) match eLCI first-order for comparability, (c) full solve only, and drop eLCI consumption as a check. Leaning (a).
- openhigh · factors · ISNE, trading periods 2023-Q1..2023-Q4 against eLCI release 1.2026-06.0The registry's residual mix is nearly twice eLCI's, for the same region and year
Found: Diffing eLCI's own ISO New England process exchanges: the residual generation mix removes 0.71pp hydro, 0.30pp solar, 0.27pp wind and 0.18pp biomass versus the generation mix -- about 1.5% of the pool, an even ~8% haircut on each renewable category. NEPOOL GIS settled, reserved or exported 39.47% of the same region's 2023 certificates, leaving an unsettled pool of 73% gas and 10% oil that reconstructs to 585.9-619.3 kg CO2e/MWh against eLCI's residual of 324.5. SECOND REGION (PJM GATS, generation months 2023-01..2023-12): registry residual reconstructs to 467.5-468.7 kg CO2e/MWh against eLCI residual_generation 394.0 (+18.7 to +19.0%), with 17.55% of the pool settled. Pricing the full GATS system mix the same way lands within 4.0% of eLCI's generation mix, so the residual gap is definitional, not mapping error. FULL SWEEP (2023, all regions with public data): NYIS registry residual 403.5 vs eLCI 229.9 (+75.5%, 23.2% of pool settled); MISO reconstructed 588.2 vs 552.9 (+6.4%, ~8.3% claimed); ERCO reconstructed 466.3 vs 482.5 (-3.4%, 16.5% claimed) -- the one region where eLCI's residual is not below the registry; CISO indicative only (Green-e CAMX 197.0 vs 217.6, different construction; WREGIS publishes nothing).
Assessment: The proportional ~8% haircut matches the scale of the voluntary green-power market, strongly suggesting eLCI's residual subtracts only voluntary claims and leaves certificates retired for state Renewable Portfolio Standard compliance in the pool. The registry's residual excludes both. These are defensible answers to two different questions -- "what is unclaimed by voluntary buyers" versus "what is unclaimed by anyone" -- but they differ by nearly a factor of two, and eLCI does not state which question its residual answers. The two registry regions bracket the effect: the gap scales with how much clean generation is actually claimed (New England: nuclear claimed to 4 certificates, 39.47% of the pool settled, +81-91%; PJM: nuclear largely unclaimed at 26.6% of the residual, 17.55% settled, +19%). eLCI's residual sits below the registry's in both. Five regions establish the shape: the eLCI-vs-registry gap scales with the settled share of the pool (ISNE 39.5% -> +81-91%; NYIS 23.2% -> +75.5%; PJM 17.6% -> +19%; MISO ~8% -> +6.4%; ERCO -3.4%). eLCI's residual behaves like a small uniform haircut everywhere; the registries' residuals move with actual claims.
Action: Registered open pending eLCI's answer to the method query. The registry data, mapping and both reconstruction variants are stored in nepool_certificate and rec_verification so the comparison reruns as new trading periods publish.
- openhigh · method · all BAsHourly figure does not trace imports
Found: The hourly EF is a generation basis: energy imported across a BA boundary is not followed to its source. Only the annual eLCI framings account for imports.
Assessment: Confirmed empirically -- observed tracks eLCI GENERATION (median gap 8.5%) better than eLCI CONSUMPTION (13.6%), which is the correct behaviour for the framing claimed.
Action: This is the Phase 2 work: populate interchange_hourly and derive an hourly consumption basis.
- openhigh · ingest · all interchange tiesThe two sides of a tie report different flows
Found: Over 5 days and 17,604 tie-hours reported from both sides: 58% agree exactly, but p90 absolute mismatch is 269 MWh and the maximum is 6,843 MWh. Relative to flow size, p90 mismatch is 53.3% and the maximum is 200%. A further 4,084 tie-hours are reported from ONE side only.
Assessment: Expected in principle -- each BA meters its own side and EIA publishes both without reconciling -- but the magnitude is large enough to change a consumption result materially, so it cannot be ignored. Flow tracing requires one flow per tie per hour.
Action: Open. Reconciliation rule to be chosen and documented; antisymmetric averaging, flow(A->B) = (v_AB - v_BA)/2, is the candidate because it guarantees conservation by construction.
- openhigh · ingest · MISO/PJM among the worstSome ties report both BAs importing simultaneously
Found: MISO->PJM reads -5,829 MWh while PJM->MISO reads -1,014 MWh for the same hour. Both negative means both BAs claim to be importing from each other, which cannot physically happen.
Assessment: Not a sign-convention misreading -- it is an inconsistency in the source. Simple averaging would produce a nonzero flow of arbitrary direction rather than flagging the contradiction.
Action: Open. These hours need detecting and either correcting or excluding, with the count disclosed; silently averaging them would launder a contradiction into a plausible-looking number.
- openhigh · ingest · WREGIS (WECC), checked 2026-08The Western Interconnection's registry publishes no certificate data
Found: WREGIS's public offering is two Excel files (generator and organization lists). No certificates issued, retired, or residual data is public; the app is login-walled throughout. Its operating rules permit aggregated publication but none is practiced. California's official Power Content Label assigns unspecified power a fixed 944 lbs/MWh default through the 2024 labels; a calculated residual begins only with the 2025 label.
Assessment: A registry-grounded residual mix for western balancing authorities cannot be built from public data. The only published 2023 analog is CRS/Green-e's CAMX rate (434.2 lbs = 197.0 kg), which subtracts all specified sales under California disclosure rules -- a different construction from the eastern registries.
Action: Recorded as a coverage gap. Green-e CAMX rate stored as an indicative CISO row in rec_verification with its scope differences noted.
- openmedium · method · Product C; also affects Product B and Product DIndustry-wide EPDs name electricity as a driver without quantifying it
Found: The industry-wide EPD for Product C reports 854 kg CO2e per declared unit across A1-A3, split 778 / 49.0 / 27.0 by module, and its interpretation names electricity generation among the principal contributors. It publishes no electricity quantity and no electricity GWP. The same gap appears in the sources for Products B and D, where electricity use is published but its GWP contribution is not.
Assessment: Without both numbers the embedded electricity factor cannot be recovered by division, and neither can the electricity share -- so a grid correction cannot be computed from the published document alone. This is not a defect in any individual EPD; the reporting rules do not require the split. But it means the single most location-sensitive input in a footprint is the one a reader cannot isolate, which is precisely what makes a correction tool necessary and simultaneously blocks it.
Action: Product C is left as a stated gap rather than filled with an estimate. Raised as a reporting question: a per-module electricity quantity and its impact would make every EPD correctable for location without re-running the model.
- openmedium · storage · ERCO known; others unmeasuredRound-trip efficiency is a default, not a measurement
Found: Storage discharge uses eta = 0.85 for every BA. ERCO's observed round-trip is 0.80 (6.80M MWh discharged against 8.51M charged across BAT and UES).
Assessment: ERCO's discharge factor is understated by roughly 6%. Other BAs are unmeasured, so the size of the error elsewhere is unknown.
Action: Open. Blocked by the storage_params coupling below.
- openmedium · ingest · MIDA, MIDW, CAL, TEX and other region codesInterchange data mixes BAs with region aggregates
Found: The interchange dataset returns rows for EIA region aggregates (MIDA->MIDW etc.) alongside genuine BA-to-BA ties.
Assessment: Including aggregates in a flow-tracing network would double-count the flows they summarise and corrupt every downstream consumption mix.
Action: Open. The ingest must filter to BA-level respondents only, using the same region exclusion list already applied elsewhere.
- openmedium · ingest · M-RETS public certificate reports, transaction year 2023M-RETS retirements cannot be restricted to MISO from public data
Found: Retirements by fuel are public (164.0M MWh in 2023) but carry no state or balancing-authority dimension, the footprint includes Manitoba, Ontario and Montana, Michigan clears through MIRECS, and parts of Illinois/Ohio clear through PJM GATS. Retired wind (119.7M MWh) exceeds MISO's entire 2023 wind generation (92.3M), so retirement volumes cannot simply be subtracted from the MISO pool.
Assessment: The MISO row uses the registry-wide claim RATE (46.11%) applied proportionally to MISO renewable generation instead of absolute volumes. This is the weakest of the reconstructions and is flagged as such; the system-mix check (+2.8%) validates only the pricing, not the claim-rate transfer.
Action: Assumption documented; improving it needs state RPS compliance filings or registry data requests.
- openmedium · factors · NYGATS Import and System Fuel Mixes report, year 2023New York's registry mixes fold imports in at certificate attributes
Found: NYGATS's "NYISO" system mix totals 147.79M MWh -- more than in-state generation -- and contains 2.13% coal although New York has had no operating coal plant since 2020. The coal matches the PJM-residual attributes NYGATS assigns to unclaimed imports (its embedded PJM residual row reproduces PJM GATS's residual exactly, incl. CO2 865.9516 lbs/MWh).
Assessment: The registry's system and residual mixes are consumption-frame constructs: unclaimed imports carry the SOURCE REGION'S RESIDUAL attributes, where eLCI's flow tracing carries source-region averages. Priced with our factors the two frames differ by +41.6% for the same year -- a definitional difference in import attribution, not an error in either.
Action: NYGATS mixes compared against eLCI consumption framings; the attribution difference is recorded here rather than folded into the residual finding.
- openmedium · storage · any BA needing an eta overrideCannot tune eta without reclassifying OTH
Found: storage_params does two jobs in one row: it sets round-trip efficiency AND opts that BA's OTH into storage treatment.
Assessment: Adding an ERCO row to correct eta would also reclassify its 578k MWh of genuine OTH generation as storage -- worse than the error being fixed.
Action: Open. Needs the two concerns separated (e.g. a nullable oth_is_storage flag) before any per-BA eta tuning. Related to issue #7.
- openlow · geometry · AKMS (eGRID layer)AKMS is not split at the antimeridian
Found: AKMS spans -179.15 to 179.78. RFC 7946 says such geometries should be split at 180 degrees.
Assessment: PostGIS has no direct splitter and a naive ST_WrapX is worse than leaving it. Affects the eGRID layer only -- no Alaska BA carries geometry -- so the choropleth is unaffected.
Action: Open, deferred. Renderers may smear AKMS across the map.
- openlow · ingest · ERCOT 2023 Annual Report on the Texas REC Trading Program (PUCT Project 55999)Texas REC retirements are published only in aggregate
Found: The report gives retirements as totals (73.05M MWh for compliance year 2023) with a REC/Compliance-Premium split but no fuel split; the per-entity retirement exhibit is confidential for one year.
Assessment: The ERCO reconstruction applies claims proportionally across renewable fuels. Because wind and solar factors are both near zero, the residual rate is insensitive to the split -- the assumption affects composition, not the emission rate, by more than ~1%.
Action: Assumption documented in the ERCO rec_verification rows.
- openlow · ingest · NEPOOL public reports, Residual Mix exportThe registry report's emission columns change unit behaviour between windows
Found: The per-certificate value of the report's Carbon_Dioxide column differs by roughly 35x between a 2023-window export and a full-history (2001-2026) export of the same report.
Assessment: The unit convention is undocumented on the export and evidently not per-certificate-stable across windows. Using these columns without understanding them would poison the comparison, so they are not loaded.
Action: Emission columns excluded from ingestion; verification prices certificate SHARES with this project's own per-fuel factors instead. Question noted for the registry help centre.
- openlow · factors · US fallback rowsUS fallback values in 0003 not reproducible
Found: Regenerating from the current library gives WAT 71.39 / WND 25.597 / OTH 1017.178 / SUN 33.545 against 0003's stored 74.959 / 27.197 / 1075.302 / 34.943 -- 4-6% apart. COL, NG, OIL, NUC, GEO, BIO match exactly.
Assessment: The stored US rows predate the library rebuild. They were deliberately NOT re-emitted, to avoid moving an existing anchor as a side effect of the fan-out.
Action: Open. Decide whether to re-derive the US fallback rows against 1.2026-06.0; it would shift factors for any BA relying on them.
- explainedhigh · verification · 15 of 61 BAs exceed their physical ceiling; explains all 10 check-3 negativeseGRID and EIA-930 assign plants to balancing authorities differently
Found: Named from eGRID2023's own plant table. eGRID assigns the Sikeston coal plant (City of Sikeston, Missouri) to BACODE=SPA, contributing 1,615 of SPA's 1,617 kt CO2e -- 99.9% of the emissions attributed to a federal hydro marketing administration. EIA-930 reports Sikeston as its OWN balancing authority, SIKE, which is not an eGRID BACODE at all. eGRID likewise assigns Centralia (coal, 4,999 kt) and five gas plants to BPAT, giving eGRID's BPAT a fuel mix of 12% gas and 4% coal against EIA-930's 3.8% gas and no coal.
Assessment: Confirmed at plant level, not inferred. Reproducing eGRID's published BA rates from its plant table gives BPAT 97.0 against the published 96.9 and SPA 237.0 against 236.7, so the rates are right -- it is the plant SET behind them that differs. EPA's own FAQ says the balancing-authority level should not be used this way: "EPA recommends using the output emissions rates from the eGRID subregion level ... Data for balancing authorities are included in eGRID as a reference." We were using a level the publisher explicitly flags as reference-only.
Action: Explained. Check 3 is re-based on subregions (0053), where the comparison is like-for-like and passes. The BA-level figures are retained as context but are no longer the basis of any pass/fail judgement.
- explainedhigh · factors · PACW; same mechanism drives its factor-coverage and multi-hop entrieseLCI's PacifiCorp West generation mix contains no fossil fuel
Found: Read directly from the exchanges of eLCI's PacifiCorp West generation-mix process, release 1.2026-06.0: HYDRO 58.51%, WIND 22.54%, SOLAR 15.89%, BIOMASS 3.06%. No gas, no coal, no oil. EIA-930 reports PACW at 38.9% natural gas over the year, between 18.9% and 53.0% in every month, and eGRID2023 measures PACW direct emissions at 140.2 kg CO2e/MWh -- a figure that only exists if there is combustion.
Assessment: This is one finding, not three. It explains all of them: the reconstruction (62.3) falls BELOW eGRID's combustion-only rate because eLCI is pricing a system with no combustion in it; the BA-specific factor share is 57.4% because eLCI publishes no gas, coal or other-fossil process for PACW to price the missing 42.6% with; and PACW is import-heavy in eLCI's consumption model because a fossil-free generator must import to serve load. The decisive evidence is internal to eLCI: it publishes `power plant construction - ngcc_const - PacifiCorp West`, a combined-cycle gas CONSTRUCTION process. It models the building of a gas fleet whose generation it does not model. That is an inconsistency inside the release, not a crosswalk failure on our side -- the process genuinely does not exist.
Action: Explained and disclosed rather than corrected: substituting our own gas share would replace eLCI's published mix with an estimate and break check 1, which is the only thing anchoring our factors to the source. PACW's eLCI-derived framings (generation 62.3, consumption 120.6) should be read as describing eLCI's model of PacifiCorp West, not the system EIA-930 and eGRID both observe. The hourly framing, built from observed generation, does not inherit the defect.
- explainedmedium · method · all BAs, NYIS worsteLCI mix vintage lags the current grid
Found: Observed NYIS runs +29.6% above eLCI's published generation mix. New York now burns 54.1% gas against eLCI's 41.7%, with less nuclear and hydro.
Assessment: A finding about the GRID, not the factors. Verified by holding the mix constant: applying our factors to eLCI's own shares reproduces its published figure to 0.0% for all 61 BAs.
Action: Explained and documented with the verification diagram and fleet-wide table.
- mitigatedhigh · ingest · 170 tie-hours of 56,897EIA-930 publishes physically impossible interchange values
Found: MISO/SWPP at 2026-08-04 01:00 reports -325,944 MWh across one tie in one hour, against an SWPP fleet on the order of 30-40 GW. 170 tie-hours exceed what BOTH endpoints generated in the same hour.
Assessment: A source data error, not a sign convention. The first reconciliation rule guarded against contradictory DIRECTION but not implausible MAGNITUDE, so this classified as `averaged` and would have produced a fabricated +163,056 MWh flow -- 50x any genuine tie. The contradiction check was defeated through the other door.
Action: Mitigated: rows exceeding combined endpoint generation are labelled `implausible` and excluded by interchange_traceable. The source stays as published in interchange_hourly and the count is reportable.
- mitigatedmedium · geometry · 143 polygon pairsBalancing-authority territories overlap
Found: HIFLD control areas are not a partition of space. Sacramento sits in BANC, CISO and WALC; Houston in ERCO and MISO. BPAT overlaps 19 others.
Assessment: Real electrical geography, not a data defect. A filled choropleth must choose a draw order, and area tracks land rather than electricity.
Action: Mitigated: fills painted largest-first, clicks resolve to the smallest containing polygon, and a node layer carries the value independent of area.
- mitigatedmedium · ingest · 12 BA-fuel pairs; material for PACW natural gas and HST natural gasEIA reports absent fuels as hourly zeros, not nulls
Found: PACW reports natural gas as exactly 0 for all 384 hours from 2025-08-16 to 2025-08-31, then jumps to normal output on 2025-09-01 and runs gas in 93% of all subsequent hours. A fleet-wide scan for fuels that report only zeros for more than seven days before their first non-zero value returns 12 BA-fuel pairs.
Assessment: A zero is indistinguishable from "not generating" in the feed, so the ingest cannot tell a fuel that is off from a fuel that is not yet being reported. The consequence is not just a missing numerator: the absent fuel is missing from the DENOMINATOR too, so the emission factor is computed over a fuel-free mix. PACW's mean factor across those hours is 157.2 against 267.3 for the rest of the record -- understated by 41% while looking entirely normal. Most of the other 10 pairs are oil peakers that genuinely idle (NEVP 16 non-zero hours in a year), where zeros are the truth.
Action: Mitigated by disclosure, not correction -- there is no way to distinguish the two cases from the feed alone, and imputing generation would invent it. Effect on PACW's annual mean is 1.8% (262.5 vs 267.3) because it is 4% of hours. The detection query is retained so new occurrences surface as the archive grows.
- mitigatedlow · geometry · CAMXCAMX includes Northwestern Hawaiian Islands
Found: CAMX carries 29 stray parts totalling 8 km2 near -178 deg -- Kure, Midway and Pearl & Hermes atolls -- which EPA's ZIP-to-subregion mapping assigns to California.
Assessment: An artifact in the EPA source, loaded faithfully. Negligible for the anchor join (0.002% of area) but it stretches the bounding box from ~10 to ~64 degrees.
Action: Mitigated at serve time only; stored geometry stays faithful to the source.
- acceptedhigh · method · NYIS, ISNE most affectedBehind-the-meter solar cannot be credited
Found: EIA-930 reports grid-scale generation only. NYIS reports 0.00% solar while eLCI assigns it 1.8%; ISNE reports 1.59%.
Assessment: Structural limit of the data source, not a defect in the method. Emission factors for regions with large distributed solar are biased HIGH and the method cannot correct it.
Action: Disclosed in Assumptions. Would need a separate distributed-generation source to address.
- acceptedhigh · factors · Every LCA or EPD that embedded an earlier eLCI electricity processThe eLCI US grid factor has fallen 26% between releases
Found: A published, critically reviewed product LCA from 2021 embedded an electricity factor of 551.1 kg CO2e/MWh, recoverable by dividing its reported electricity GWP contribution by its reported electricity use. The current eLCI release (1.2026-06.0) publishes the US consumption mix at 405.3 kg CO2e/MWh at grid and 420.6 at user -- 26.5% lower, with no change of location, boundary or method.
Assessment: This is not an error in either figure. The US grid decarbonised, and eLCI tracked it. But it means every product footprint carrying an older eLCI electricity process is now high on its electricity term by roughly a quarter, and nothing in the published document signals that -- the release is usually cited, but the magnitude of drift between releases is not. A practitioner comparing an EPD from 2021 against one from 2026 is comparing two different grids as much as two different products.
Action: Surfaced in the correction tool, which requires the embedded factor as an input rather than assuming the current release. Guessing would silently fold the vintage shift into the location correction and misattribute a quarter of the difference.
- acceptedhigh · method · Two facility EPDs, same manufacturer, same product, same practitioner and PCRTwo EPDs for one product differ 45% on grid alone
Found: One facility reports 532 kg CO2e per declared unit using a hydro utility's electricity dataset; the other reports 772 using a fossil-heavy utility's. A 240 kg CO2e gap, 45%, for the same product from the same company. Our hourly at-user intensities for those two grids differ by 503.5 kg CO2e/MWh, implying 477 kWh per declared unit -- inside the published range for electric-arc melting plus rolling. On that basis electricity is about 2% of the first facility's footprint and about 32% of the second's.
Assessment: A sixteen-fold difference in electricity share for one product, caused by location alone. It is the strongest available demonstration that a grid assumption is not a background detail: for this product class it is either negligible or the largest single lever, and which one depends entirely on where the plant sits. It also shows the correction can be recovered from published documents even when neither states the electricity -- but only because two exist for the same product. For a product with one EPD, it cannot.
Action: Recorded as Product C with the derivation and its upper-bound caveat stated. Strengthens the reporting request in epd-no-electricity-breakout: a per-module electricity quantity would make this recoverable from a single document rather than from a lucky pair.
- acceptedhigh · method · 60 BAs, 490,381 BA-hours, 2025-08-16..2026-08-18Annual import weights understate the multi-hop correction eightfold
Found: Solved over OBSERVED hourly interchange, the gap between recursive and first-order accounting is: Tacoma Power +159.7%, Douglas County PUD +105.4%, Seattle City Light +88.9%, Puget Sound Energy +53.8%, Chelan PUD +32.2%, Portland General +22.0%, Grant County PUD -21.1%. The same calculation on eLCI's ANNUAL import weights gave +18.6%, +18.7% and +4.6% for the first, third and fourth of those.
Assessment: Not a disagreement about method -- both runs use the identical solver. The difference is entirely in the weights, and it is systematic rather than noisy. Hourly imports concentrate: a hydro utility runs on its own water most of the time and buys fossil power in specific hours, so annual averaging blends the dirty hours into the clean ones and the multi-hop correction largely disappears. For Tacoma Power the annual figure understates it by a factor of 8.6. Practitioners using eLCI's published consumption mixes for an import-dependent region are getting a number whose temporal aggregation has removed most of the effect being corrected for. The distribution is heavy-tailed, not uniform: the median BA gap is 0.45% and 35 of 60 are under 1%, so this matters enormously for a handful and barely at all for most.
Action: Both bases are published per hour in consumption_mix_hourly rather than one being chosen. Recorded here because the annual-vs-hourly difference is a finding about eLCI's published consumption mixes, not about this tool.
- acceptedhigh · method · 595,969 BA-hours, 2025-08-16..2026-08-18The interchange network does not close, and cannot be made to
Found: 13,017 of 519,633 modelled BA-hours (2.51%) export more than their own generation plus imports can account for. Measured in ENERGY rather than hours the same gap is 406,709 MWh, or 0.08% of exports. Separately, 84,247 BA-hours (14.1%) have an endpoint whose generation is never ingested. Network-wide imbalance is exactly zero, because the reconciliation rule is conserving by construction.
Assessment: Not noise and not fixable: generation, each neighbour's generation and every tie are separate measurements by separate operators. The two ways of counting differ by a factor of thirty, and that gap is itself the finding -- nodes are short by a little, often, rather than by a lot, ever. Reporting only the hour count would badly overstate the problem. The deficit concentrates in GWA (25.7% of its exports), TIDC (6.6%), SEPA (1.1%) and SPA (0.8%): power marketing administrations and generation-only entities that sell output EIA attributes to a different BA's generation, so they permanently export power they do not report generating.
Action: Accepted as the design premise. Consumption shares are normalised over INBOUND energy (own generation plus imports), which is non-negative by construction and sums to 1 whatever the exports do -- so an imbalance changes the CONFIDENCE in a factor, never its arithmetic validity. Published per BA in ba_energy_balance and on the About page.
- acceptedhigh · method · 47,981 of 490,381 BA-hoursOne BA-hour in ten contains energy no source can price
Found: 9.78% of BA-hours have some inbound energy arriving from one of the six unpriceable endpoints; 5,818 hours exceed 10% and the maximum is 50.0%. Southwestern Power Administration averages 11.5% unpriced across the year. Separately, 6.42% of BA-hours have contradictory or implausible ties excluded from their import basis.
Assessment: This is the cost of the rule that unpriceable energy is never given a neighbour's mix. The alternative -- substituting a nearby factor -- would make every hour look complete and would be an invention. Renormalising over priced inbound instead means the published factor describes the priced FRACTION of inbound energy: a statement of scope. In an hour where half the inbound energy is unpriceable, the factor is still arithmetically valid and still describes only half the energy.
Action: Disclosed per hour rather than in aggregate: unpriced_share and excluded_share are columns on every row of consumption_mix_hourly, so a consumer filtering for high-confidence hours can do so without recomputing anything. Stated as an assumption on the About page.
- acceptedmedium · method · NYIS; also MISO (10 subregions), SWPP and PJM (8 each)One balancing authority can span very different grids
Found: NYISO is a single balancing authority covering the NYUP, NYCW and NYLI eGRID subregions, whose 2023 direct rates are 110.1, 392.7 and 539.5 kg CO2e/MWh -- a factor of five apart. Our BA-level factor is 312.3 for all three. 13 of 69 BAs span more than one subregion; MISO spans ten.
Assessment: Not an error and not fixable at this resolution. A balancing-authority average is the unit EIA-930 publishes on, so a tool built from it inherits the unit's granularity. For a user in upstate New York the BA average overstates intensity roughly threefold; for one in New York City it understates it. This is the single largest source of spatial error in the tool and it is structural.
Action: Disclosed on the About page beside the subregion table. Cannot be resolved without sub-BA generation data, which EIA-930 does not publish.
- acceptedmedium · factors · ~31 BAsHalf the fleet partly priced on national factors
Found: eLCI publishes processes for some of a BA's fuels and not others. PACW is ~51% BA-specific, JEA 56%, FMPP 71%; HST is 0%.
Assessment: Not an error, but a partly-national factor is indistinguishable from a fully BA-resolved one unless the share is stated. It was invisible before ba_factor_basis() was added.
Action: Disclosed: the share is shown in the detail panel whenever it is below 100%, and carried in the ladder response.
- acceptedmedium · geometry · all BA territoriesBA boundaries come from a dataset no longer hosted
Found: Both sources originally specified are gone: the EIA Atlas layer and HIFLD Open both return 404. Geometry comes from a 2025-04 archived snapshot obtained via DataLumos.
Assessment: A point-in-time archive, not a live source. It will not reflect later boundary changes, and cannot be refreshed from the original publisher.
Action: Disclosed in Data sources. Any future boundary change requires finding a new source.
- acceptedmedium · factors · HSTHST admitted on national fallback factors
Found: City of Homestead publishes 17,853 current hourly rows but eLCI has no generation processes for it -- only a consumption mix.
Assessment: Excluding it left a permanent hole where data plainly exists. It is essentially single-fuel gas, so the national gas factor is a reasonable approximation, but the level is not BA-resolved.
Action: Admitted via ba_ingest_override with a stated reason, and flagged in the panel as national-average.
- acceptedmedium · ingest · 1,348,677 tie-hours, 2025-08-16..2026-08-18Four tie-hours in ten are not a clean agreement
Found: agreed 772,142 (57.25%), averaged 340,225 (25.23%), single_sided 217,111 (16.10%), contradictory 17,899 (1.33%), implausible 1,300 (0.10%).
Assessment: Only 57% of tie-hours have both sides agreeing exactly. 25% require averaging two disagreeing reports, 16% have no independent confirmation at all, and 1.4% are unusable. Any consumption figure built on this inherits an uncertainty larger than the precision a life-cycle factor is conventionally quoted to. The full year is slightly better than the first two-week sample suggested (57.25% against 54%), so the earlier figure was pessimistic rather than wrong.
Action: Disclosed. interchange_flow exposes only the traceable 98.6% so a caller cannot forget to filter, and interchange_quality() reports the split.
- acceptedmedium · method · 6 of 71 endpoint codesSix tie endpoints have no emission factor from any source
Found: Of 71 codes appearing in interchange_hourly, 60 are ingested hourly and 5 more are priceable from an eLCI generation mix (BCHA 47.1, HQT 8.9, IESO 88.4, MHEB 14.3, NBSO 213.2). Six have no factor from any source: AESO, SPC, CEN, SWPW, BHBA, SIKE.
Assessment: The five terminal nodes were not a data gap but a CROSSWALK gap -- eLCI publishes them under entity names never mapped to their EIA codes. MHEB matters most: it exports ~2,161 MWh/hour into MISO and imports nothing, so it is a pure source node whose energy was previously unattributable. Searching eLCI's entity names for the remaining six returned two confident false positives: CEN matched "Public Service Company of New Mexico" on the string "Mexico" (CEN is a CFE control area in Baja California), and SWPW matched "Southwest Power Pool" on "Power Pool" (SWPW is a sub-area, not the pool). Either would have fabricated a factor from a string coincidence -- the same failure mode as SEPA/SPA in the BA crosswalk.
Action: The five identifiable terminal nodes are pinned BY INSPECTION in tie_endpoint, never by name similarity. The remaining six are recorded as unpriced, so energy arriving from them is reported as unattributable rather than silently assigned a neighbour's mix.
- acceptedmedium · method · 3,255 of 42,176 ZIP codesOne ZIP code in thirteen belongs to more than one subregion
Found: EPA's Power Profiler crosswalk maps 38,921 ZIPs to a single eGRID subregion, 3,130 to two and 125 to three. EPA states the cause plainly: a ZIP "may fall in multiple eGRID subregions because it is supplied by different service providers associated with different subregions", and their own tool asks for the service provider to resolve it.
Assessment: Nothing in a ZIP code alone settles this, so any tool that accepts a ZIP and returns one factor is guessing for 7.7% of inputs. The spread between candidates can be large -- 07401 in New Jersey resolves to either RFCE or NYUP, whose hourly at-user intensities differ by roughly a third.
Action: All candidates are stored with EPA's own ranking and the choice is presented to the user rather than made for them. The correction tool shows the alternatives and says why it cannot choose.
- acceptedlow · ingest · AEC, EEI, GRIF, NSBFour BAs never report generation by fuel
Found: All four appear in EIA's fuel-type respondent list and report demand, but have filed zero generation-by-fuel rows in two years.
Assessment: Single-plant and small municipal operators that mostly buy power and settle through interchange. The series does not exist.
Action: Disclosed in Assumptions.
- acceptedlow · geometry · BHBA, GLHB, SIKE, SWPWFour EIA BAs have no territory polygon
Found: These BAs exist in EIA-930 but are absent from the 2025-04 HIFLD archive.
Assessment: They post-date the archive snapshot. They will render as gaps regardless of data coverage.
Action: Disclosed. Would require a newer boundary source, which does not currently exist publicly.
- acceptedlow · method · Worked example at 3.26% electricityA grid correction is bounded by the electricity share, which is usually small
Found: For the worked example, electricity contributes 1.532 kg CO2e of a 46.96 kg CO2e footprint. Correcting a 551.1 kg CO2e/MWh assumption to the measured hourly at-user intensity moves the total by between -0.34% (RFCM) and -1.86% (CAMX) depending on the plant location.
Assessment: The bound is the useful result, and it cuts both ways. Where electricity is a few percent of a footprint, a grid correction is not worth arguing about however wrong the assumption was -- and presenting it prominently would imply a precision the rest of the study does not have. Where electricity dominates, the same difference is the single largest lever in the assessment. A tool that returned only the correction, without the share, would invite the first mistake.
Action: The electricity share is returned first and stated before the correction throughout the interface.
- acceptedlow · method · 11 BAseGRID percentages unstable for hydro-dominated BAs
Found: Eleven BAs have an eGRID rate below 5 kg CO2e/MWh -- mostly hydro-dominated federal marketers. SEPA's vintage-matched check 3 reads +4267%.
Assessment: A percentage against a near-zero denominator explodes and carries no information.
Action: Marked in the verification table; those rows should be read as absolute differences.
- acceptedlow · verification · eGRID2023 against a 2025-08 to 2026-08 observation windoweGRID is a 2023 measurement and eGRID2024 has slipped
Found: eGRID2023 covers calendar year 2023, released 2025-01-15 and revised to 2025-06-12. EPA's detailed-data page states "Next planned release: eGRID2024 in January of 2026". As of the eGRID landing page's own last update on 2026-07-28, eGRID2023 remains the current edition, so eGRID2024 is at least seven months late.
Assessment: A two-to-three year gap between the reference measurement and the observation window is unavoidable rather than a choice -- eGRID2023 IS the latest edition. It sets a floor on how closely check 3 can be expected to agree, and it biases in a known direction: the grid has continued decarbonising, so our observed figures should sit slightly below a same-boundary 2023 measurement. That is visible in the three small negatives at subregion level.
Action: Accepted and dated. Worth re-running the subregion check when eGRID2024 lands, since roughly half the residual disagreement should close if the vintage explanation is right.
- acceptedlow · geometry · eGRID layereGRID subregion polygons are ZIP-derived
Found: The shapefile lineage shows 2024 USA ZIP Code polygons dissolved by subregion, not service territories.
Assessment: Fine for the regional anchor join and for rendering; boundary-adjacent point-in-polygon is approximate.
Action: Disclosed. Do not make facility-level claims from this layer.
- acceptedlow · ingest · HGMAHGMA stopped reporting in June 2025
Found: New Harquahala filed 7,349 hours of natural-gas generation and then stopped on 2025-06-03.
Assessment: Cause unknown -- possibly mothballed, sold, or exited BA status.
Action: Left in the request set so it reappears if reporting resumes.
- resolvedhigh · factors · AVRNeLCI and EIA-930 disagree about which plants ARE Avangrid Renewables
Found: eLCI gives WIND 82.66%, SOLAR 13.26%, GAS 4.08%. EIA-930 reports WND 60.9%, NG 39.1% and SOLAR exactly 0.0% across all 8,887 hours, the gas being one unit peaking at 554 MWh/h and running in 7,841 of them. AVRN has only two ties, BPAT and PACW, and net-exports 99% of what it generates.
Assessment: A fleet does not lose an entire solar portfolio and gain a baseload combined-cycle plant in one revision, so this is not a vintage gap -- it is two different plant sets under one name. eLCI's 83/13/4 reads as Avangrid the COMPANY; EIA-930's 61/39/0 reads as the Pacific Northwest subset that registers as a balancing authority. The vintage-matched check 3 is -69.3%, putting eLCI's figure below eGRID's combustion-only rate, which cannot hold for one system.
Action: Resolved in 0061 by withholding rather than explaining. Serving eLCI's figure under the AVRN code asserts an identity the evidence disputes -- the same class of error as SEPA/SPA -- so the eLCI annual framings are no longer served for AVRN. Withheld, not deleted: the rows stay, the reason is published beside the gap, and upstream query elci-avrn-entity-scope names what would settle it. AVRN's hourly framings are built from observed generation and are unaffected.
- resolvedhigh · verification · 22 eGRID subregions, 4,322 TWhAt the level EPA recommends, the factors validate
Found: Aggregating our balancing-authority factors up to eGRID subregions by eGRID's own plant-level generation shares: fleet-wide life-cycle 408.4 kg CO2e/MWh against eGRID's direct 347.6 -- +17.5%. 16 of 22 subregions are positive.
Assessment: A life-cycle result must exceed a combustion-only one, and +17.5% is a plausible magnitude for upstream fuel and plant construction across a national grid. This is the strongest external validation the project has: eGRID is the only source independent of both EIA-930 and eLCI, so it is the check that would catch an error the other two share. Of the six negatives, three are New York -- NYIS is ONE balancing authority spanning NYUP, NYCW and NYLI, carrying a single factor of 312.3 against subregion realities eGRID puts at 110.1, 392.7 and 539.5. The remaining three (NWPP -8.4%, RMPA -6.0%, SRMW -5.9%) are small and consistent with a 2023 measurement against a 2025-26 window on a grid still getting cleaner.
Action: Published on the About page as the primary form of check 3.
- resolvedhigh · factors · HSTThe HST admission was justified on row count, not generation
Found: Migration 0023 admitted City of Homestead on the stated grounds that "EIA publishes current hourly generation (~100% natural gas)". Homestead self-generates 198 MWh across the year: 175 usable hours out of 8,788, and 0.0% of its generation priced with BA-specific factors.
Assessment: My own decision, and the premise confused rows with generation -- the rows exist and are almost all zero. Checked against the rest of the fleet before acting, because a threshold rule would have been better than a special case if this were a category. It is not: HST is the only BA that fails on all three measures at once. The next-worst usable-hours share is 48%, the next-smallest annual generation is 227x larger, and every other sparse BA is fully BA-resolved.
Action: Resolved in 0061. The override is withdrawn, so HST is no longer ingested, and it is excluded from the hourly framings -- an intensity computed over 198 MWh entirely on national fallback factors is not a regional grid intensity and should not sit beside CISO's on the same map. Its eLCI CONSUMPTION framings remain served, because eLCI does publish a consumption mix for Homestead, which is the correct description of a utility that buys nearly all its power. Existing rows are kept; the exclusion is reversible.
- resolvedhigh · factors · MISOMISO hydro rated dirtier than coal
Found: MISO HYDRO came out of the fan-out at 1702.6 kg CO2e/MWh -- the highest of 42 eLCI HYDRO processes against a median of 9.7.
Assessment: Not real data. The vendored library was built from eLCI 1.2025-06.0, whose process UUIDs already returned {"deleted": true} from the live Commons API. The current release gives 35.3.
Action: Rebuilt the library from eLCI 1.2026-06.0 and re-derived every factor (migration 0009). Fixed at source rather than overridden.
- resolvedhigh · read path · choropleth_values(), every map load and every region clickMap queries scaled with the size of the archive, not the request
Found: choropleth_values() aggregated the whole of emission_factor_hourly twice per request: once grouping by ts to select one quorum hour out of ~8,760, once averaging total_mwh to produce 60 marker sizes. At 511,926 rows this took 5.4s cold and 2.7s warm against a 3s statement timeout on the anon role, returning HTTP 500.
Assessment: The function did not change; the table grew 35x when the full-year generation backfill landed. The query was always O(archive) for two answers that do not depend on the request, so it was always going to cross the limit -- the backfill only set the date. This is the failure mode that never appears in development, where the table is small.
Action: Resolved in 0034. Both answers are materialised: ef_hour_coverage (~8,760 rows) and ef_ba_scale (60 rows), refreshed by refresh_emission_factor_hourly() alongside their source. Cold cost fell from 5.4s to under 0.1s and no longer tracks the length of the archive.
- resolvedhigh · read path · interchange_reconciled, granted to anonThe reconciliation view recomputed the whole archive on every read
Found: Building the balance view did not time out -- it killed the database backend, connection closed. `select ba_a, ts from interchange_traceable limit 1` sequentially scans all 96 generation_hourly partitions and aggregates the entire table, because the plausibility bound was computed from an inline aggregate. The balance query referenced the view twice, so it paid that cost twice over 2.48M interchange rows.
Assessment: The third instance of cost-scaling-with-the-archive found in one session, and the only one that had not fired yet: interchange_reconciled is granted to anon, so the first UI feature to read it would have got a full aggregate of two multi-million-row tables against a 3s statement timeout. Raising work_mem made it worse rather than better -- more memory per parallel worker on a query that was already the problem.
Action: Resolved in 0042. generation_total_hourly (517,374 rows) and interchange_flow (1,329,478 rows, indexed on both endpoints) are materialised, so the expensive work happens once per ingest rather than once per read. interchange_reconciled stays a plain view so the netting rule remains changeable without re-ingesting.
- resolvedhigh · read path · /api/ef/snapshot, all requests without an explicit tsThe snapshot endpoint served a six-month-old hour as current
Found: ef_snapshot() defaulted to the latest hour where EVERY covered BA reported. At 60 BAs that hour was 2026-02-24 07:00, while 57 of 60 reported at 2026-08-17 03:00. The response carried no indication the hour was stale, and stated ba_count 60 for the full covered set rather than the BAs actually present.
Assessment: The same defect 0022 fixed in choropleth_values four migrations earlier, left in place here because the construct was duplicated rather than shared. Unanimity does not scale: the worst reporter sets the date for everyone, so adding BAs makes the default hour monotonically older. Three BAs that never report concurrently were enough to push it back half a year.
Action: Resolved in 0034. Both functions now call ef_quorum_ts(0.8), a single definition of the default hour, so they cannot diverge again. ba_count now reports the BAs present at the hour and covered the full set.
- resolvedmedium · verification · All 61 BAs; materially AVRN and BPATChecks 2 and 3 compared an unweighted mean against weighted ones
Found: The observed figure was an UNWEIGHTED mean of hourly emission factors, while eLCI's published mix factor and eGRID's rate are both GENERATION-WEIGHTED. Fleet-wide the bias has a median of 0.00% and only AVRN (+25.3%) and BPAT (+15.7%) exceed 10%, but it inflated AVRN's check 2 from +440% to +576%.
Assessment: Correcting it made the results WORSE, which is the outcome that deserves less suspicion. Check 3 negatives went from 9 to 10: PACE turned negative (+10.7 to -8.1) and BPAT (-33.0 to -74.7), NWMT (-2.4 to -24.3) and LDWP (-5.6 to -19.5) all deteriorated. The unweighted basis had been flattering them by accident.
Action: Resolved in 0049. Both bases are stored -- the unweighted mean answers "what was the intensity in a typical hour" and remains a legitimate figure, it is simply not what eLCI and eGRID publish. check_2_unweighted_pct and check_3_unweighted_pct preserve the previously published numbers.
- resolvedmedium · method · ba_energy_balance, first definitionMy first deficit metric measured our coverage, not the grid's imbalance
Found: The original unaccounted_export_mwh summed export-minus-inbound across ALL endpoints. Over a two-week sample it looked sensible. Over the full year its top five entries were IESO, BCHA, MHEB, HQT and NBSO -- 23.7 TWh, dwarfing everything else -- every one of them with zero hours of negative demand.
Assessment: The metric was wrong, not the data. Those five are Canadian interties whose generation this pipeline never ingests, so their inbound is imports alone and everything they export scores as a deficit. That is a statement about our coverage, not about the grid failing to balance. Combined into one figure it put the headline at 4.73% and buried the real inconsistency, which is 0.08%. The two-week sample was too short to expose it -- the terminal nodes had not yet accumulated enough volume to dominate.
Action: Resolved: split into deficit_mwh (modelled endpoints only -- a genuine inconsistency) and unmodelled_export_mwh (a coverage statement). Of the 24.9 TWh crossing unmodelled endpoints, 24.2 TWh is now priceable from an eLCI annual mix and only 688 GWh is genuinely unattributable.
- resolvedmedium · method · 490,381 BA-hours across 8,791 hours and 60 BAsThe hourly solver reproduces its controls exactly
Found: ERCOT, essentially islanded, returns consumption first-order 352.1, consumption recursive 352.1 and generation 352.1 -- identical to one decimal, with own_share exactly 1.000. MISO, PJM and SWPP, large and near self-sufficient, agree within 0.2%. CISO returns consumption 217.7 against generation 185.3, imports being dirtier than its own fleet, which is the expected direction for California. Every one of the 490,381 rows solved; no singular systems arose in any hour.
Assessment: The islanded case is the strongest available check: an isolated grid MUST have consumption equal to generation, so any error in the share normalisation, the import direction convention or the matrix assembly would show up there. It does not. That the recursive system was non-singular in all 8,791 hours also means no source-free cycle occurred -- there was never a group of BAs importing only from each other with none generating.
Action: No action. Recorded because a solver that agrees with its controls should say so as explicitly as one that does not.
- resolvedmedium · ingest · consumption_mix_hourlyThe hourly consumption mix now refreshes on the interchange cron
Found: The solve lived in numpy while the cron surface is a Next.js route, so consumption_mix_hourly was only as current as the last manual run even when generation and interchange were both fresh.
Assessment: The obstacle looked like infrastructure and was actually mathematics. The recursive basis solves (I - S) c = b, which appears to need a linear algebra library -- but that system IS the Neumann series, and the fixed-point iteration c <- S c + b computes it whenever the spectral radius of S is below 1. S is substochastic here because each row sums to the share of priced inbound energy from other modelled BAs. Measured over a stratified sample of the year the maximum row sum is 0.991968, convergence takes 15 iterations worst case, and the result agrees with an exact numpy solve to 5.65e-09. No external scheduler, no secrets outside the existing deployment, and no second language in the pipeline.
Action: Resolved. solve_consumption_mix() runs in-database over a trailing 3-day window, called by /api/ingest/interchange at :20 -- after generation lands at :00, so both inputs are fresh. Verified against the numpy output row for row over 3,904 BA-hours: maximum difference 5.0e-07 on every column, which is the 6-decimal rounding in the Python CSV writer rather than solver disagreement. The script is retained for full rebuilds, where numpy is far faster.
- resolvedmedium · read path · 21,545 of 511,926 EF rows (4.2%); 6 BAs materiallyIdle BAs were counted as reporting
Found: ef_hour_coverage counted BAs with a ROW rather than BAs with a non-null factor, so /api/ef/choropleth announced 57 of 60 at the current hour when 54 carried a value. The other three rendered blank on the map while being counted as present. Affected: HST 98.0%, SEPA 51.6%, WWA 46.4%, YAD 45.7%, GWA 20.1%, DEAA 16.1%.
Assessment: A BA that generated nothing has no intensity, which is correct -- but it is not coverage either. The count is the reader's only evidence of how complete the map is, so overstating it by three is a direct overstatement of completeness.
Action: Resolved in 0037. Quorum and every reported count now use a usable-factor count; the snapshot reports idle BAs separately so "no data" and "no generation" stay distinguishable. The quorum HOUR was unaffected.
- resolvedmedium · ingest · /api/ingest/interchangeInterchange had no scheduled ingest
Found: Generation has had an hourly cron since 0017. Interchange had only a manual backfill script, so the dataset underpinning every consumption framing would have silently stopped being current the moment the backfill ended.
Assessment: ingest_run had no dataset discriminator, so adding a second cron would have made an interchange run -- which touches no generation data -- the answer to "when was generation last updated". The freshness panel would have claimed currency it did not have, twice an hour, with nothing surfacing it. That is the exact invisibility 0017 was created to fix.
Action: Resolved. Route added on a :20 schedule, offset from the generation cron at :00. ingest_run.dataset added first (0038) and ingest_status() reports the two datasets separately.
- resolvedmedium · read path · /grid/correction, every load of the threshold boxThe materiality thresholds recomputed 490k rows per page view
Found: materiality_thresholds() derived its timing leverage with a window function over all ~490k solved BA-hours on every call. Against the anon role's 3s statement timeout it failed on a cold cache and succeeded after a refresh, so the correction page intermittently rendered its fallback box -- the fifth instance of read cost scaling with the archive, and the first shipped after the pattern had been named four times.
Assessment: The leverages change only when the consumption solve changes, so per-request recomputation bought nothing. The works-after-refresh signature is the same one 0034 diagnosed; it was recognisable from the report alone.
Action: Resolved in 0081: materiality_leverage is materialised (one row), the function is arithmetic over it, and it refreshes on the same hook as the solve.
- resolvedlow · method · validation coverageConsumption-mix reconstruction was wrongly deferred
Found: The plan recorded validation against eLCI's consumption mix as impossible before Phase 2. In fact only the OBSERVED-consumption comparison needs interchange data; reconstructing eLCI's published consumption figure from its own declared weights needs nothing new.
Assessment: Two different checks had been conflated. The reconstruction is available now and doubles as a golden reference for the flow-tracing implementation: given eLCI's own import weights, correct code must reproduce eLCI's consumption mix.
Action: Reconstruction confirmed exact for three BAs; to be run fleet-wide and added to the verification table as check 4.
- resolvedlow · method · solve_consumption_mix()The iterative solver reports whether it converged
Found: A fixed-point iteration that hits its cap without converging still holds a value. Returning it would produce a plausible number from an unconverged solve.
Assessment: Convergence depends on the spectral radius of S staying below 1, which holds only because every network component contains a node that generates. A source-free cycle -- BAs importing solely from each other with none generating -- would push a row sum to exactly 1 and the iteration would never settle. None occurred in 8,791 hours, but that is a property of the data rather than of the method, and the data changes hourly.
Action: The function stops on convergence rather than on the iteration cap, returns iterations and final_delta, and marks affected rows `unconverged` rather than `ok` if the cap is reached. The ingest route logs a warning on a non-converged run.
- resolvedinfo · method · all 60 consumption entitiesFirst-order reconstruction reproduces eLCI consumption exactly
Found: Applying eLCI's own declared import shares to source BAs' generation mixes reproduces eLCI's published consumption figure for 60 of 60 entities, all within 0.05%.
Assessment: Confirms our reading of how the published consumption LCI was constructed: a single-hop weighted average of source generation mixes. It is now check 4, and it doubles as the reference the flow-tracing implementation is validated against.
Action: Closed. Stored in consumption_check.
All sources are public US government data. Every figure on the map can be exported with its boundary, method, release and source process identifier attached, so any number can be traced back to the process it came from.
Disclaimer
This project is developed purely out of academic intrigue. It is not a commercial product, a compliance tool, or professional advice of any kind.
It is built on United States Government data - EIA-930, the EPA/NETL US Electricity Baseline (eLCI), and EPA eGRID - which is used responsibly and cited throughout. Any error in the processing, interpretation or presentation of that data is mine and not the publishing agencies'. Nothing here is endorsed by, affiliated with, or approved by any government agency.
The outputs of this page should be used at the user's own risk. I make no warranty that any figure is accurate, complete, or fit for any particular purpose, and I bear no responsibility or liability for any decision taken on the basis of them. The limitations I have found are documented openly on the About page and in the discrepancy register - that register is a record of what I have found, not an assurance of what remains.
This work presents only my own opinions, if any. It reflects no position or opinion of my employer.