01 / 01
· HOOK

Wattlas

European electricity, explained. Open data on how and when the price of power moves across the continent — pre-computed into views you can actually read, and rebuilt on a schedule from the sources.

wattlas.net · Pulse
The Pulse view — average price by hour of day
A working tool you can open right now, not a pitch.
· 35 VIEWS · SIX QUESTIONS

Not a menu of tools — six questions about power

An editorial landing routes you into one of six plain-language questions; each opens a section of views that answer it. Every view can still compare up to six bidding zones at once — here Germany against France, the Netherlands and Austria.

01 · The Daily RhythmWhen does power move?
02 · What's on the GridWhat's flowing through the wires?
03 · Geography of PriceWhere does power flow — and why do prices split?
04 · When the Grid is TestedWhat happens when supply runs tight?
05 · The BillWhat does it cost, and who pays?
06 · The ChargeWhat's plugging into the grid?
/panels · zone compare
Wattlas comparing four bidding zones
Grouped by the question you came to answer, not by how it was built.
· SECTION 01

When does power move?

The Daily Rhythm

Electricity has no single price — it has a price every hour. This is how it swings between cheap and expensive, day to day and year to year.

PulseThe duck curve — prices crater at midday when solar floods in, then spike after dark.
SpreadThe daily gap between the cheapest and dearest hour — the signal storage lives on.
Negative PricesThe hours the grid pays you to consume, promoted to a metric of their own.
Capture PriceWhat a solar or wind MWh actually earns once it's worth least when there's most of it.
HistorySeveral years of daily spread, free to roam — zoom, fold onto a season, read the trend.
Chart · 1 of 5

Pulse

When is power cheapest, and when does it cost the most?
Average day-ahead price by hour of day — the duck curve. Solar floods the midday hours and drags the price toward (and often below) zero; then it spikes after sunset as demand peaks and solar drops out. Weekday against weekend, per zone.
−€18 → €142midday vs evening, average hour
/pulse
Pulse view
Chart · 2 of 5

Spread

How wide is the gap between the cheapest and dearest hour each day?
The daily top-to-bottom spread — the signal a battery lives on — averaging roughly €96/MWh. Negative-price days are flagged, and a perfect-foresight arbitrage figure is shown, always labelled an unachievable upper bound, never a revenue promise.
€96/MWhaverage daily top–bottom spread
/spread
Spread view
Chart · 3 of 5

Negative Prices

How often does the grid pay you to consume?
The hours the wholesale price falls below zero — promoted from a footnote to a metric of its own. A per-calendar-year bar reads the multi-year rise (DE-LU 139 → 576 hours, 2021 → 2025), the current year marked YTD; drill into any year's calendar. Reconciled to BNetzA (2024 = 457, 2025 = 573). Kept, never clipped.
139 → 576 hDE-LU per year, 2021 → 2025
/negative-prices
Negative prices view
Chart · 4 of 5

Capture Price

What does a megawatt-hour of solar or wind actually earn?
Generation-weighted capture price ÷ baseload = the value factor. German solar earns least exactly when there's most of it — cannibalization. An annual line reads the decline across five years: DE solar 0.78 → 0.52 (2021 → 2025), the 2022 gas crisis the one outlier. Computed from real data, anchors cited.
0.78 → 0.52DE solar value factor, 2021 → 2025
/capture-price
Capture price view
Chart · 5 of 5

History

Is the daily spread widening over the years?
Three years of daily spread, free to roam — zoom into a week, fold the series onto a seasonal curve, and read the longer-run trend. The volatility that storage and flexible demand are racing to monetise, laid out in one long series.
3 yrof daily data
/history
History view
· SECTION 02

What's flowing through the wires?

What's on the Grid

Behind every price is a physical mix of fuels. This is what generates Europe's power hour to hour — and how clean, or dirty, each hour really is.

Generation MixFull generation by fuel for any zone — France's nuclear against Germany's wind and solar.
Carbon IntensityHow many grams of CO₂ each kilowatt-hour carries, computed from the live mix.
Residual LoadDemand minus wind and solar — the load conventional plant and batteries must still cover.
Marginal FuelA model of when gas sets the price — CCGT cost against the day-ahead, hour by hour.
Chart · 1 of 4

Generation Mix

What actually generates the power, and how do countries differ?
Full generation by fuel for any zone, two side by side — France's flat nuclear baseload against Germany's volatile wind and solar. Gaps in the upstream data render as gaps, never fabricated zeros, and the fuel palette is identical in every view.
2-zoneside-by-side compare
/generation-mix
Generation mix view
Chart · 2 of 4

Carbon Intensity

How clean is each hour of the grid?
Production-based carbon intensity computed from the live mix — from ~30 gCO₂/kWh on a renewable-heavy French hour to ~550 on a coal-heavy Polish one. Low when wind and solar peak, high when fossil plant sets the margin. The lifecycle methodology is stated, not buried.
30 → 550gCO₂/kWh, FR vs PL
/carbon-intensity
Carbon intensity view
Chart · 3 of 4

Residual Load

How much load is left once wind and solar have run?
Demand minus wind and solar — the residual that dispatchable plant and batteries must still cover. It peaks in the evening, when solar has gone but demand hasn't: the gap a weather-dependent grid has to plan around, hour by hour and zone by zone.
eveningpeak residual hour
/residual-load
Residual load (mismatch) view
Model · 4 of 4

Marginal Fuel

Why is the price what it is?
A model, not a measurement: modelled CCGT marginal cost against the day-ahead price shows gas setting it on roughly 77% of days. The gas input is a labelled proxy and the inference is flagged as a model — the view never claims to have measured the marginal unit directly.
~77%of days gas is marginal
/marginal-fuel
Marginal fuel view
· SECTION 03

Where does power flow — and why do prices split?

Geography of Price

One country, one price — until the grid can't carry the power across it. Four countries, four answers to the same congestion problem, on the map.

DivergenceHow far neighbouring zones' prices drift apart — and the flow that explains it.
Germany North–SouthWind in the north, demand in the south, one price — so clean power gets curtailed.
France NuclearThe centralised mirror: 57 reactors, who exports, who imports, what it costs.
Nordic Price ZonesThe split Germany debates, already live — a cheap hydro north, a dear south.
UK RegionalBritain's answer: keep one price, pay Scottish wind ~£2 bn a year to switch off.
CurtailmentClean power the grid can't move — the cost of the bottleneck, in MWh and €.
Locational SignalThe internal north–south congestion made legible; the single-zone debate, even-handed.
Chart · 1 of 7

Divergence

How far do neighbouring zones' prices drift apart, and why?
Monthly price gaps between adjacent zones, alongside the physical cross-border flow that explains them, with congestion flagged. The headline is DE↔FR: when the interconnector saturates, one price becomes two.
DE↔FRthe headline price gap
/divergence
Divergence view
Map · 2 of 7

Germany North–South

Why is northern wind stranded from the demand down south?
Wind in the windy north, industry in the south, one price between them — so clean power gets curtailed and the grid pays to reroute it. ~400 Landkreise mapped by installed capacity, the control-area balance, and the single-zone debate laid out even-handedly.
~400Landkreise mapped
/germany-north-south
Germany North-South grid story
Map · 3 of 7

France Nuclear

Where does France's centralised fleet sit, and when does it dip?
The centralised mirror of the German story: ~63 GW across ~18 sites and 57 reactors, mapped by région, with the spring/summer maintenance dip, who exports and who imports, and the declared availability ceiling drawn over actual output.
~63 GWnuclear fleet, ~18 sites
/france-nuclear
France nuclear story
Map · 4 of 7

Nordic Price Zones

What does the split-zone market Germany debates actually look like?
The split Germany argues about, already running: twelve zones from a cheap hydro north (~€26/MWh) to a dear, continent-coupled south (~€90). The within-country divergence, shaded on the map — the lesson next door.
12 zones€26 → €90/MWh
/nordic-bidding-zones
Nordic price zones story
Map · 5 of 7

UK Regional

What does keeping one price across Britain cost?
Britain's answer to the same problem: keep one national price and pay Scottish wind around £2 bn a year to switch off when the grid can't carry it south. Carbon intensity region by region, and the constraint bill that one price hides.
£2 bn/yrconstraint payments
/uk-regional
UK regional story
Chart · 6 of 7

Curtailment

How much clean power does the grid throw away — and why?
Curtailed renewable energy the grid couldn't move, spiking on stormy, negative-price hours — presented as a managed grid-stability measure, in MWh and €. Fails open to "awaiting source" if the upstream feed is down, rather than guessing.
stormy daysspikes on neg-price hours
/curtailment
Curtailment view
Chart · 7 of 7

Locational Signal

Why does the north–south split show in neither flows nor prices?
The bottleneck is internal to the single DE-LU bidding zone, so it is invisible to both cross-border flow and the one price. Shown as congestion evidence — with no simulated split price; the contested split-zone case is presented as a cited range, annotated, not asserted.
1 zoneDE-LU, debate annotated
/locational-signal
Locational signal view
· SECTION 04

What happens when supply runs tight?

When the Grid is Tested

A renewable grid's hardest hours — the windless, sunless spells it must plan for, the batteries that ride the gap, and the day the lights actually went out.

DunkelflauteThe cold, dark, windless spells when wind and solar all but vanish and the price climbs.
StorageThe batteries that live off the daily spread — charging cheap midday, discharging into the peak.
Capacity & AdequacyCan firm capacity cover the worst residual-load hours — and what the policy to ensure it costs.
Iberian BlackoutA sober, sourced replay of 28 April 2025 — what the grid data recorded, asserting no cause.
Chart · 1 of 4

Dunkelflaute

What happens when wind and solar vanish for days at a time?
The cold, dark, windless spells when renewables all but disappear. It auto-detects the worst stretch, showing the firm-power/import stack and the price climb — now with a worst-spells-on-record table across five years (14 spells, 2021–2025), the widely-reported November and December 2024 events (down to 0.2% of demand) included.
14 spellson record, 2021 → 2025
/dunkelflaute
Dunkelflaute story
Chart · 2 of 4

Storage

Can a battery earn off the daily price swing?
The batteries that live off the spread — charging cheap at midday, discharging into the evening peak. A transparent arbitrage model labelled an upper bound, alongside where grid storage is actually being built (~6× the capacity since 2021).
~6×grid storage since 2021
/storage
Storage story
Chart · 3 of 4

Capacity & Adequacy

Can firm capacity cover the worst hours — and what does ensuring it cost?
Whether dependable capacity can meet the toughest residual-load hours, and the policy written to guarantee it — Germany's provisional ~12 GW gas tender. The adequacy question a weather-dependent grid can't dodge, with its price tag flagged as provisional.
12 GWgas tender, provisional
/capacity-adequacy
Capacity and adequacy view
Historical · 4 of 4

Iberian Blackout

How does a national grid go dark within seconds, and come back?
28 April 2025, replayed from the record: Portuguese load to the floor (~0.1 GW), then the sourced, hour-by-hour restoration. A deliberately sober account that cites the official ENTSO-E investigation and asserts no cause of its own.
~0.1 GWPT load at the floor
/iberian-blackout
Iberian blackout story
· SECTION 05

What does it cost, and who pays?

The Bill

The wholesale price is only the start. This is the economic and consumer half — what flexibility is worth, and how a megawatt-hour becomes your monthly bill.

FlexibilityWhat a shiftable load — EV, heat pump, battery — saves charging in the cheapest hours.
Retail WedgeYour bill decomposed: wholesale, grid fees, levies and taxes — and how it has shifted.
Industrial PricesWhat heavy industry pays — DE against France, Spain and Norway, honestly bounded.
Curtailment in €The price tag on wasted wind: curtailed MWh × a reference rate, a labelled estimate.
Chinese Solar ImportsWhat Europe pays for Chinese solar — customs values per month and per kilogram.
Chart · 1 of 4

Flexibility

What does shifting load to the cheapest hours save?
What a shiftable load — an EV, a heat pump, a home battery — saves over a year by charging in the cheapest hours instead of on a flat tariff. A labelled upper bound (perfect foresight, no losses), framed as the ceiling on the prize, not a guaranteed cut to your bill.
upper bound€/yr vs flat tariff
/flexibility
Flexibility view
Chart · 2 of 4

Retail Wedge

What is actually in your electricity bill?
The wholesale price is a minority of it. Your bill split into energy & supply, network charges, and taxes & levies — Germany ~€0.39/kWh, only ~40% energy. Eurostat, annual, country-level, and how the wedge has shifted over time. Stated plainly: EUR/kWh ≠ our €/MWh.
3 partswholesale · grid · taxes
/electricity-bill-breakdown
Retail wedge view
Chart · 3 of 4

Industrial Prices

What does heavy industry pay — and where does Wattlas stop?
Industrial electricity prices, Germany against France, Spain and Norway, country-level from Eurostat. Honestly bounded: it is a country-level comparison, not a plant-level one — and the view says exactly that rather than implying a precision the data can't carry.
DE vs FR/ES/NOEurostat, country-level
/industrial-power-prices
Industrial prices view
Chart · 4 of 4

Curtailment in €

What does thrown-away wind cost?
The price tag on curtailment: curtailed MWh × a reference rate, a running annual estimate — labelled an estimate, not the actual bill. The economic shadow of the north–south bottleneck, the same data from the Geography section taken one question further.
€ est.running annual total
/curtailment#cost
Curtailment cost view
· SECTION 06

What's plugging into the grid?

The Charge

Millions of cars and the first electric trucks are becoming the grid's newest, most flexible load. Eight views — and every number on them says whether it's a fact, a target or a projection.

Charging NetworkGermany's public charge points — how many, how fast, who runs them, and a district-by-district map.
Europe ComparedThe EU's million-plus points, most in just three countries — against the AFIR corridor targets.
The Price JungleWhat public charging actually costs — a spread so wide the competition authority investigated.
Demand on the GridWhat EVs draw today (an estimate, ~1% of demand) against the scenarios for 2030.
Vehicle-to-GridThe rules arrived, the first offers launched — realized participation still near zero.
Trucks & BusesHeavy-duty, honestly split: buses in service by the thousand, truck charging mostly a tender.
Charging EconomicsIs fast charging profitable? One audited operator says: not yet, but closer.
The 2035 QuestionBrussels reopened the phase-out — competing estimates, cited, with no verdict.
Map + charts · 1 of 8

Charging Network

How big is Germany's public charging network, and where is it?
The Bundesnetzagentur's register aggregated to one scoreboard: 204 038 public charge points across 113 364 stations (~8.8 GW), the operators grouped to brand, the build-out since 2010, and a Landkreis choropleth that places every single point. Public points only — the register itself says the real network is larger.
204 038public charge points, July 2026
/ev-charging-network
Charging network view — KPIs and charge points by operator
Map · same view

District by district

Which districts have charging — and which are left behind?
The same register, on the map: every one of the 204 038 public charge points placed into its Landkreis — 100% matched by name, nothing guessed. The network leans visibly west and south; a district with no register entry renders as "no data", never as zero. Boundaries from Eurostat GISCO — no map tiles, still a static page.
400Landkreise, every point placed
/ev-charging-network
Public charge points per Landkreis — choropleth of Germany
· ACT II · HOW IT'S BUILT

How it's built

The product stands on its own. What follows is purely technical: the build, the pipeline, and the data sources behind it.

↓ scroll for the engineering
· BUILD · CLAUDE + GITHUB

Built with Claude Code, shipped through GitHub

Each view was built as a small vertical slice: a prompt stating the goal and success criteria, then code with an offline test, then a pull request. A human approved every step before it merged.

Prompt
goal + success criteria
Claude Code
pipeline · test · frontend
Pull request
to GitHub
Review
human approval
Merge
to main

The same flow as its sibling project, StockScore: small steps, each gated, each reviewable in a diff.

The model did the typing; the gates, tests and review kept it honest.
· CI/CD · GITHUB

A cron, a commit, a redeploy

The pipeline is the only code that touches the APIs; it writes small JSON the frontend reads directly. A GitHub Action reruns it twice a month and commits the data; Firebase Hosting redeploys. No backend, no database.

Open-data APIs
ENTSO-E, NESO, MaStR…
Pipeline
Python / pandas
data/*.json
pre-aggregated, committed
Firebase Hosting
static, no backend

On the 1st and 15th at 05:17 UTC the Refresh-data workflow rebuilds every view and commits only what changed. The heavy MaStR bulk download runs in the same job, isolated and non-fatal.

The whole "backend" is a scheduled job that writes files.
· DATA SOURCES

Nine open feeds, plus curated, cited tables

A stack of public sources, each with its own auth, units, lag and refresh cadence, reconciled to one canonical shape — anything not licence-clean is flagged.

ENTSO-E
Day-ahead prices, generation, load and cross-border flows for every EU bidding zone — plus a one-time frozen 5-year history (2021–2025) behind the trend views.
Each refresh + frozen 5-yr · API token
NESO
Great Britain regional carbon intensity, plus Scottish wind constraint payments.
Each refresh · Open API
MaStR
Germany's Marktstammdatenregister: every individual wind and solar installation.
Weekly · Open bulk export
SMARD
Bundesnetzagentur: per-control-area generation and net balance (German field names).
Each refresh · Open API
ODRÉ / RTE
France's éCO2mix régional and national generation, plus an RTE nuclear-availability overlay (currently paused — awaiting Unavailability-API access).
Each refresh · Open API + OAuth
netztransparenz
German TSOs: curtailed (abgeregelt) renewable energy by period.
Each refresh · OAuth client
Eurostat
Household & industrial electricity price components (energy / network / taxes).
Each refresh (annual data) · Open API
World Bank
TTF gas benchmark for the marginal-fuel model (CC BY 4.0, converted with ECB rates) — licence-clean since it replaced the old Yahoo proxy.
Monthly · CC BY 4.0
BNetzA Ladesäulenregister
Every public charge point in Germany — operator, power, district, commissioning date. Feeds the whole EV section.
Twice-monthly · CC BY 4.0
EEX EUA
EU carbon (EUA) price from primary auctions — curated, slow-moving, stated as-of.
On edit · Curated

Cadence: the refresh runs twice a month (the 1st and 15th, 05:17 UTC); the RTE overlay is paused, Eurostat's underlying data is annual, and the curated tables move on edit. Plus Eurostat GISCO map boundaries.

· DATA MANAGEMENT

How the sources are kept honest

IsolationEach source is its own pipeline module; one failure can't break the others.
Fail openA missing key writes status:"unavailable" and the view shows "awaiting source" (netztransparenz, RTE, Eurostat, Yahoo, UK constraints); the core ENTSO-E builders instead stop the run rather than commit a half-empty file.
LandminesThe non-obvious traps are documented and coded around: the Oct-2025 resolution break, the 23/25-hour DST days, zones that aren't regions.
Units statedMWh vs GWh, gCO₂/kWh, production- vs consumption-based carbon — labelled in code and on screen.
Tested offlinePure metric functions run on inline fixtures — 156 offline tests, no network needed; the backfill adds seam + DST-year-length coverage.
Resampled to hourly, grouped in local time, every join written down.
· OPEN IT

Open it.

Everything here is live and public. Explore the six sections and their views, or read how each number is computed.

European electricity, explained and verifiable.