Congestion & Constraints

Transmission constraints, shadow prices, interface limits, and congestion-rights results that show where the grid restricted power transfers and affected prices.

58 datasetspublished by ATG DataMISO14ISONE9ERCOT7PJM7CAISO6NYISO6SPP6US reference3

Congestion & Constraints datasets
DatasetRows
MISOAnnual real-time constraint historyATG Data·MISO·MISO's Annual real-time constraint history. Each row preserves a publisher record, workbook row, or report document with its source member and row index. Source timestamps, units, geographic scope, and revision qualifiers are retained in record_json; event_time is collection time; completed_at is when the entire document became available.399.0K2025
NYISOAvailable & Total Transfer CapabilityATG Data·NYISO·NYISO available transfer capability and total transfer capability by interface and market run. The source rows are melted so DAM and HAM timesteps can be compared by interface over time.15.6M1999
CAISOCAISO Day-Ahead Binding ConstraintsATG Data·CAISO·Which transmission facilities bound in CAISO's day-ahead market and what each one cost, one row per interval and constraint. 463,496 rows, 2015-01 to now. Columns: event_time, constraint_name, shadow_price_usd_mwh, plus constraint_cause. The shadow price is the marginal cost of the binding limit — what the market would have saved from one more megawatt of capability on that element. This is the table that answers WHY congestion appeared; a price spread between two locations shows that they separated but not which facility separated them.477.8K2015
CAISOCAISO Real-Time Binding ConstraintsATG Data·CAISO·Which transmission facilities bound in CAISO's real-time market and what each one cost, one row per interval and constraint. 6.43M rows, 2015-01 to now. Columns: event_time, constraint_name, shadow_price_usd_mwh, plus constraint_type ('intertie', 4.06M rows, or 'nomogram', 2.36M), direction, and constraint_cause. The shadow price is the marginal cost of the binding limit — what the market would have saved from one more megawatt of capability on that element. This is the table that answers WHY congestion appeared; a price spread between two locations shows that they separated but not which facility separated them.6.6M2015
CENACE Constraint Shadow PricesATG Data·US reference·Daily shadow price and opportunity cost of each binding constraint on the mainland (SIN), by CENACE's constraint code.——
SPPConstraint Identity EvidenceATG Data·SPP·Bitemporal, source-backed identities for SPP binding constraints. Each row preserves the raw operator ID and footprint, exact monitored-facility, contingent-facility, contingency and public flowgate context, evidence locator and version, observed and authoritative effective intervals, match method, confidence, review status, and resolution status. Source-exact and reviewed-exact mappings are distinguished from unresolved, contradictory, and rejected rows. The canonical constraint ID is an SPP source identity, not a physical line or substation ID.147.6K2026
SPPConstraint Identity QualityATG Data·SPP·One quality row per identity build: observed and distinct raw IDs, resolved/partial/unresolved/contradictory/rejected counts, resolution rate, stale reviewed mappings, one-to-many cases, missing footprint markers, SPP East/West ambiguity, and any source-key loss. This reports the evidence boundary rather than inflating resolution with text or geographic guesses.42026
ERCOTConstraint Shift Factor RunsATG Data·ERCOT·One row per COMPLETED nightly estimation of ERCOT constraint shift factors, and the only record that a run finished. Resolve the latest usable run here — computed_at = (SELECT max(computed_at) FROM atg.ercot_constraint_sensitivity_runs) — and never off max(computed_at) of the sensitivities themselves, because a run writes its rows in blocks that all carry the new timestamp and an unfinished or abandoned run would otherwise look like the newest one. Each row also carries how much evidence that run had: interval_coverage is the fraction of published dispatch intervals that survived admission, intervals_refused_unexplained counts intervals showing congestion with no constraint recorded as binding (an unobserved binding set), constraint_feed_lag_minutes is how far the constraint feed trailed the price feed, and constraints_seen / constraints_in_fit / constraints_reported show how many constraints bound, how many were good enough to control for, and how many earned a published estimate.382026
CAISOConstraint Shift Factor RunsATG Data·CAISO·One row per COMPLETED nightly estimation of CAISO constraint shift factors, and the only record that a run finished. Resolve the latest usable run here — computed_at = (SELECT max(computed_at) FROM atg.caiso_constraint_sensitivity_runs) — and never off max(computed_at) of the sensitivities themselves, because a run writes its rows in blocks that all carry the new timestamp and an unfinished or abandoned run would otherwise look like the newest one. Each row also carries how much evidence that run had: interval_coverage is the fraction of published dispatch intervals that survived admission, intervals_refused_unexplained counts intervals showing congestion with no constraint recorded as binding (an unobserved binding set), constraint_feed_lag_minutes is how far the constraint feed trailed the price feed, and constraints_seen / constraints_in_fit / constraints_reported show how many constraints bound, how many were good enough to control for, and how many earned a published estimate.342026
MISOConstraint Shift Factor RunsATG Data·MISO·One row per COMPLETED nightly estimation of MISO constraint shift factors, and the only record that a run finished. Resolve the latest usable run here — computed_at = (SELECT max(computed_at) FROM atg.miso_constraint_sensitivity_runs) — and never off max(computed_at) of the sensitivities themselves, because a run writes its rows in blocks that all carry the new timestamp and an unfinished or abandoned run would otherwise look like the newest one. Each row also carries how much evidence that run had: interval_coverage is the fraction of published dispatch intervals that survived admission, intervals_refused_unexplained counts intervals showing congestion with no constraint recorded as binding (an unobserved binding set), constraint_feed_lag_minutes is how far the constraint feed trailed the price feed, and constraints_seen / constraints_in_fit / constraints_reported show how many constraints bound, how many were good enough to control for, and how many earned a published estimate.362026
PJMConstraint Shift Factor RunsATG Data·PJM·One row per COMPLETED nightly estimation of PJM constraint shift factors, and the only record that a run finished. Resolve the latest usable run here — computed_at = (SELECT max(computed_at) FROM atg.pjm_constraint_sensitivity_runs) — and never off max(computed_at) of the sensitivities themselves, because a run writes its rows in blocks that all carry the new timestamp and an unfinished or abandoned run would otherwise look like the newest one. Each row also carries how much evidence that run had: interval_coverage is the fraction of published dispatch intervals that survived admission, intervals_refused_unexplained counts intervals showing congestion with no constraint recorded as binding (an unobserved binding set), constraint_feed_lag_minutes is how far the constraint feed trailed the price feed, and constraints_seen / constraints_in_fit / constraints_reported show how many constraints bound, how many were good enough to control for, and how many earned a published estimate.262026
ERCOTConstraint Shift Factors (Estimated)ATG Data·ERCOT·Estimated sensitivity of every ERCOT pricing location's price to every binding transmission constraint: one row per constraint, contingency, and location, recomputed nightly over a rolling 60-day window. This is what answers 'which nodes drive this constraint' and 'which constraints is this node exposed to'. Covers ERCOT's transmission constraints with their contingency and both named terminals, over 1,123 settlement points. shift_factor is in the ISO's orientation — POSITIVE means an incremental MW injected at that node increases loading on the constraint and the node is paid below system lambda while it binds; NEGATIVE means generation there relieves the constraint and earns a premium. These are ESTIMATES recovered from the price identity LMP = energy - sum(shift_factor x shadow_price), not a published PTDF matrix. They are measured RELATIVE TO THE MARKET'S REFERENCE — the identity yields SF(node) - SF(reference), so a single absolute value should be quoted as 'relative to the system reference' rather than as the node's PTDF, while DIFFERENCES between nodes are exact because the reference term cancels. Three further differences from a published matrix: they describe a NODE (a generator at that node inherits its location's value, and two units at one node are indistinguishable), they reflect the topology actually in effect across the window including outages rather than a stated base case, and every one carries a std_error from a 200-draw block bootstrap that resamples whole days. Read std_error before quoting shift_factor: an estimate whose absolute value is not at least twice its standard error is not distinguishable from zero. estimation_status says why a row has no number — 'thin_support' (in the fit, so it is controlled for, but under 12 binding intervals or under 3 distinct binding days), 'no_support' (under 3 binding intervals; not a regressor), or 'collinear' (it bound in lockstep with another constraint, so the two cannot be separated). Where from_station and to_station are populated they identify the monitored element and are NOT the constrained direction — the sign of shift_factor is what says which way. Every read must pin computed_at to one run, and must resolve that run through the companion atg.<iso>_constraint_sensitivity_runs ledger rather than off max(computed_at) here — rows are written in blocks that all carry the new timestamp, so an unfinished or abandoned run would otherwise look like the newest. Mixing runs averages a node across different network topologies.15.2M2026
CAISOConstraint Shift Factors (Estimated)ATG Data·CAISO·Estimated sensitivity of every CAISO pricing location's price to every binding transmission constraint: one row per constraint, contingency, and location, recomputed nightly over a rolling 60-day window. This is what answers 'which nodes drive this constraint' and 'which constraints is this node exposed to'. Covers CAISO's INTERTIE AND NOMOGRAM constraints, not internal transmission branches, over roughly 19,400 pricing nodes. CAISO publishes no contingency or terminal names on this feed, so contingency_name, from_station and to_station are always empty. shift_factor is in the ISO's orientation — POSITIVE means an incremental MW injected at that node increases loading on the constraint and the node is paid below system lambda while it binds; NEGATIVE means generation there relieves the constraint and earns a premium. These are ESTIMATES recovered from the price identity LMP = energy - sum(shift_factor x shadow_price), not a published PTDF matrix. They are measured RELATIVE TO THE MARKET'S REFERENCE — the identity yields SF(node) - SF(reference), so a single absolute value should be quoted as 'relative to the system reference' rather than as the node's PTDF, while DIFFERENCES between nodes are exact because the reference term cancels. Three further differences from a published matrix: they describe a NODE (a generator at that node inherits its location's value, and two units at one node are indistinguishable), they reflect the topology actually in effect across the window including outages rather than a stated base case, and every one carries a std_error from a 200-draw block bootstrap that resamples whole days. Read std_error before quoting shift_factor: an estimate whose absolute value is not at least twice its standard error is not distinguishable from zero. estimation_status says why a row has no number — 'thin_support' (in the fit, so it is controlled for, but under 12 binding intervals or under 3 distinct binding days), 'no_support' (under 3 binding intervals; not a regressor), or 'collinear' (it bound in lockstep with another constraint, so the two cannot be separated). Where from_station and to_station are populated they identify the monitored element and are NOT the constrained direction — the sign of shift_factor is what says which way. Every read must pin computed_at to one run, and must resolve that run through the companion atg.<iso>_constraint_sensitivity_runs ledger rather than off max(computed_at) here — rows are written in blocks that all carry the new timestamp, so an unfinished or abandoned run would otherwise look like the newest. Mixing runs averages a node across different network topologies.170.5M2026
MISOConstraint Shift Factors (Estimated)ATG Data·MISO·Estimated sensitivity of every MISO pricing location's price to every binding transmission constraint: one row per constraint, contingency, and location, recomputed nightly over a rolling 60-day window. This is what answers 'which nodes drive this constraint' and 'which constraints is this node exposed to'. Covers MISO's binding real-time constraints over its hub and zone roll-up of roughly 325 pricing locations, so the answers are coarser than a full nodal set. MISO publishes no contingency or terminal names, so contingency_name, from_station and to_station are always empty. shift_factor is in the ISO's orientation — POSITIVE means an incremental MW injected at that node increases loading on the constraint and the node is paid below system lambda while it binds; NEGATIVE means generation there relieves the constraint and earns a premium. These are ESTIMATES recovered from the price identity LMP = energy - sum(shift_factor x shadow_price), not a published PTDF matrix. They are measured RELATIVE TO THE MARKET'S REFERENCE — the identity yields SF(node) - SF(reference), so a single absolute value should be quoted as 'relative to the system reference' rather than as the node's PTDF, while DIFFERENCES between nodes are exact because the reference term cancels. Three further differences from a published matrix: they describe a NODE (a generator at that node inherits its location's value, and two units at one node are indistinguishable), they reflect the topology actually in effect across the window including outages rather than a stated base case, and every one carries a std_error from a 200-draw block bootstrap that resamples whole days. Read std_error before quoting shift_factor: an estimate whose absolute value is not at least twice its standard error is not distinguishable from zero. estimation_status says why a row has no number — 'thin_support' (in the fit, so it is controlled for, but under 12 binding intervals or under 3 distinct binding days), 'no_support' (under 3 binding intervals; not a regressor), or 'collinear' (it bound in lockstep with another constraint, so the two cannot be separated). Where from_station and to_station are populated they identify the monitored element and are NOT the constrained direction — the sign of shift_factor is what says which way. Every read must pin computed_at to one run, and must resolve that run through the companion atg.<iso>_constraint_sensitivity_runs ledger rather than off max(computed_at) here — rows are written in blocks that all carry the new timestamp, so an unfinished or abandoned run would otherwise look like the newest. Mixing runs averages a node across different network topologies.3.4M2026
PJMConstraint Shift Factors (Estimated)ATG Data·PJM·Estimated sensitivity of every PJM pricing location's price to every binding transmission constraint: one row per constraint, contingency, and location, recomputed nightly over a rolling 60-day window. This is what answers 'which nodes drive this constraint' and 'which constraints is this node exposed to'. THE DAY-AHEAD MARKET, not real time: this estimate is fitted to day-ahead marginal values against day-ahead nodal congestion and it describes day-ahead congestion. It covers PJM's day-ahead binding constraints with their contingency over roughly 14,450 pricing nodes. PJM names no terminals, so from_station and to_station are always empty. PJM's real-time shadow prices ARE ingested now (pjm_rt_marginal_value, pjm_transmission_limits) but no estimate has been fitted to them and no atg.pjm_constraints_rt canonical table exists yet — a real-time PJM answer needs that fitting work, not a new ingest. shift_factor is in the ISO's orientation — POSITIVE means an incremental MW injected at that node increases loading on the constraint and the node is paid below system lambda while it binds; NEGATIVE means generation there relieves the constraint and earns a premium. These are ESTIMATES recovered from the price identity LMP = energy - sum(shift_factor x shadow_price), not a published PTDF matrix. They are measured RELATIVE TO THE MARKET'S REFERENCE — the identity yields SF(node) - SF(reference), so a single absolute value should be quoted as 'relative to the system reference' rather than as the node's PTDF, while DIFFERENCES between nodes are exact because the reference term cancels. Three further differences from a published matrix: they describe a NODE (a generator at that node inherits its location's value, and two units at one node are indistinguishable), they reflect the topology actually in effect across the window including outages rather than a stated base case, and every one carries a std_error from a 200-draw block bootstrap that resamples whole days. Read std_error before quoting shift_factor: an estimate whose absolute value is not at least twice its standard error is not distinguishable from zero. estimation_status says why a row has no number — 'thin_support' (in the fit, so it is controlled for, but under 12 binding intervals or under 3 distinct binding days), 'no_support' (under 3 binding intervals; not a regressor), or 'collinear' (it bound in lockstep with another constraint, so the two cannot be separated). Where from_station and to_station are populated they identify the monitored element and are NOT the constrained direction — the sign of shift_factor is what says which way. Every read must pin computed_at to one run, and must resolve that run through the companion atg.<iso>_constraint_sensitivity_runs ledger rather than off max(computed_at) here — rows are written in blocks that all carry the new timestamp, so an unfinished or abandoned run would otherwise look like the newest. Mixing runs averages a node across different network topologies.165.3M2026
ERCOTCRR Monthly Auction ResultsATG Data·ERCOT·Cleared ERCOT monthly Congestion Revenue Right auction awards, one row per source-to-sink CRR and time-of-use block, including awarded MW and the auction shadow price per MWh. This is public auction evidence for who acquired a path and at what clearing price. It does not contain realized day-ahead congestion settlements, fees, later trades, the holder's full portfolio, or net profit, so auction cost must not be described as payout or profitability. The official source is ERCOT report NP7-803-M.1.5M2025
MISODaily day-ahead binding constraintsATG Data·MISO·MISO's Daily day-ahead binding constraints. Each row preserves a publisher record, workbook row, or report document with its source member and row index. Source timestamps, units, geographic scope, and revision qualifiers are retained in record_json; event_time is collection time; completed_at is when the entire document became available.4.0K2026
SPPDay-Ahead Binding ConstraintsATG Data·SPP·Transmission constraints binding in SPP's day-ahead market, published hourly for the delivery day with the opaque constraint ID, constraint type, NERC flowgate ID where present, binding state, source-published monitored and contingent facilities, contingency name, and the E/W interconnect marker. Pairs with the real-time table to compare which exact source identities the day-ahead market anticipated. This feed does not publish direction, flow, or limits, and its facility labels are source context rather than physical topology matches.1.4M2017
MISODay-Ahead Binding ConstraintsATG Data·MISO·The named transmission constraints that bound in MISO's day-ahead market, one row per constraint per operating hour, with the signed shadow price in dollars per MWh. constraint_name describes the flowgate as a monitored element under a contingency; branch_name is the monitored element itself, with branch_type LN for a line and XF for a transformer, and from_ca and to_ca its control areas. A row establishes that the constraint bound in the cleared day-ahead solution for that hour and its marginal system cost. It does not, by itself, identify which pricing node the constraint affected or whether it also bound in real time; those claims require shift-factor or direct attribution evidence. Distinct from miso.binding_constraint, which counts real-time binding constraints and names none of them. MISO restates this history, so read the latest load per constraint and hour.21.3K2026
PJMDay-Ahead Constraint Marginal ValuesATG Data·PJM·What each binding day-ahead transmission constraint cost in PJM, hour by hour: the monitored facility, the contingency facility, and the constraint's marginal value — its shadow price, the saving from one more MW of headroom. This is the table that says how hard a constraint bound, where pjm_da_transconstraints says only that it did. PJM PUBLISHES THIS VALUE AS A NEGATIVE NUMBER: 2,654,985 negative rows against 43 positive over the table's full history, which reaches back to 2010. Read its magnitude as the cost of the constraint and do not compare its sign against another market's. This answers day-ahead congestion only; for real-time, see pjm_transmission_limits and pjm_rt_marginal_value. Source: PJM Market Data.2.7M2010
ISO-NEDay-Ahead ConstraintsATG Data·ISONE·ISO-NE day-ahead transmission constraints with constraint, contingency, interface flag, and the publisher-signed marginal_value. The source values use the opposite sign from Ask the Grid's canonical shadow price, so analytical ranking should use atg.isone_constraints_da; a non-zero value is cleared day-ahead congestion evidence, not proof of a real-time binding condition.25.8K2022
NYISODay-Ahead Limiting ConstraintsATG Data·NYISO·NYISO day-ahead limiting-constraint records for the market-clearing plan, including limiting facility, facility PTID, contingency, and constraint cost. Paired with day-ahead LBMP components, it helps explain expected congestion and transfer limits before real-time operations.1.0M2001
MISODay-ahead reserve-product constraintsATG Data·MISO·MISO's Day-ahead reserve-product constraints. Each row preserves a publisher record, workbook row, or report document with its source member and row index. Source timestamps, units, geographic scope, and revision qualifiers are retained in record_json; event_time is collection time; completed_at is when the entire document became available.1542026
ERCOTDay-Ahead Shadow Prices & Binding ConstraintsATG Data·ERCOT·Binding transmission constraint and contingency pairs from ERCOT's Day-Ahead Market solution, one row per constraint, contingency, and delivery hour, including the limiting facility, its from and to stations, the constraint limit, flow, and violation in MW, and the shadow price. A row establishes that the named constraint bound in the cleared day-ahead solution for that hour and its marginal system cost. It does not, by itself, identify which settlement point or hub the constraint affected, or establish that the constraint bound in real time; the first requires shift-factor or direct attribution evidence, and real-time binding is recorded in the SCED shadow prices. The official source is ERCOT report NP4-191-CD.3.6M2017
MISODay-ahead subregional power-balance constraintsATG Data·MISO·MISO's Day-ahead subregional power-balance constraints. Each row preserves a publisher record, workbook row, or report document with its source member and row index. Source timestamps, units, geographic scope, and revision qualifiers are retained in record_json; event_time is collection time; completed_at is when the entire document became available.952026

About congestion & constraints data

Constraint and transfer-capability data helps explain why prices at two locations separated, not just that they did. The catalog includes binding-constraint records, marginal values and shadow prices, available and total transfer capability, and ERCOT congestion-revenue-right auction results; each describes a different operational or financial layer of congestion.