Battery revenue simulator
A linear program over a year of hourly prices1, and what it says about how long a battery should be.
A grid battery makes its living the way a hibernating ground squirrel does. It takes in more than it needs when the taking is good, sits on the surplus, and spends it when nothing else is available. The squirrel's constraint is how much fat it can carry. The battery's is how many hours of energy it can hold. The question is the same in both cases. At what point does carrying more stop paying for itself?
This model dispatches a one-megawatt battery against 8,760 hourly prices by linear programming2, in monthly blocks with the state of charge carried across the joins. Every megawatt hour of throughput is charged a cycling cost3, so the optimiser cannot trade for free, and round-trip efficiency is split symmetrically as the square root per leg.
Duration value flattens
| Duration | Net revenue, $/kW-year | Equivalent cycles | Hours at rated output |
|---|---|---|---|
| 2 hours | 98.1 | 1,361 | 1.85 |
| 4 hours | 107.1 | 786 | 3.71 |
| 8 hours | 111.0 | 424 | 7.42 |
Doubling from two hours to four buys about nine per cent more revenue. Doubling again from four to eight buys under four. On energy arbitrage alone the value of duration flattens hard past four hours4. The reason is unglamorous. There are only so many hours in a day when the price spread is worth crossing, and a longer battery cannot manufacture more of them.
The longer battery also cycles far less, which matters for a warranty argument even where it does not matter for revenue. The eight-hour case turns over about a third as many equivalent cycles as the two-hour case.
Revenue against storage duration. The curve bends at about four hours.
A summer week of dispatch. Charging fills the solar belly of the day; discharge meets the evening peak.
Sensitivity to round-trip efficiency and degradation cost.
The price series: duration curve and average daily shape.
The code
Python reference implementation using an open solver, a JuMP and HiGHS port, an Octave port, and the dispatch workbook. The archive holds the source only: no generated figures, no bulk
data. Each model runs from its own README.md.
Download source · 216 KB All code
Sources
Numbered markers in the text above point here. Emission factors, cost ranges and lifespan figures are representative values from these sources, not measurements made for this project.
- ERCOT, Day-Ahead Market Settlement Point Prices, historical archive.The price shape the synthetic year is calibrated to reproduce.
- Sioshansi, Denholm, Jenkin & Weiss, Energy Economics, 2009 - estimating the value of electricity storage under perfect foresight.The perfect-foresight dispatch formulation and its upper-bound character.
- Mongird et al., Grid Energy Storage Technology Cost and Performance Assessment, Pacific Northwest National Laboratory, 2020.Degradation cost per megawatt hour of throughput, and round-trip efficiency.
- Denholm et al., The Four-Hour Challenge, National Renewable Energy Laboratory, 2019.Why duration value flattens past four hours.