A battery storage project is bought on a spreadsheet and lived through a dispatch algorithm. The spreadsheet specifies power, energy and a capital cost. The algorithm decides, every hour for twenty-five years, whether to charge, discharge, hold, or idle — and that sequence of small decisions is what actually produces the revenue and consumes the asset. Two projects with identical bills of materials, in the same market, can differ by 10–15% in lifetime economics purely because of how they are operated.

This page is about the operating half: what people mean when they say BESS optimization, how an optimizer is actually formulated, why a revenue-maximizing optimizer quietly destroys value, and — importantly — the things no optimizer can fix no matter how good the solver is.

The core argument: dispatch optimization is not a revenue calculator. It is a constrained cost-minimization problem run over a rolling horizon, and its most valuable term is usually not the price forecast but the cycling cost — the price the optimizer charges itself for wearing the cells. Get that term wrong and every other input is wasted, because the optimizer will spend your battery on spreads that do not cover its own damage.

What "BESS optimization" actually means

The phrase is used for at least three different problems, and most confusion about storage modeling comes from not separating them. They have different decision variables, different time horizons, and different failure modes.

Sizing optimization decides how much to build. Decision variables are power (MW), energy (MWh) and often duration. It runs once, at design stage, and its output is a capital cost and an equipment list. This is the problem solved by capacity optimization — linear programming or a search over candidate configurations, evaluated against a year of hourly data and rolled forward across the project life.

Dispatch optimization decides how to operate what was built. Decision variables are charge power, discharge power, grid import, grid export, diesel output and resulting state of charge at every timestep. It runs continuously for the life of the asset, and in real systems it re-solves every dispatch interval.

Multi-objective optimization is what you get when the true objective is not a single number — for example minimizing LCOE while also meeting a reliability constraint, or maximizing revenue subject to a hard cap on annual throughput for warranty compliance. These are usually handled by weighting, by treating one objective as a constraint, or by generating a Pareto frontier for the owner to choose from.

The coupling between the first two is the point most often missed. The optimal size depends on the dispatch it will be run with. If you size a battery against a fixed rule-based controller and then operate it with an economic optimizer, you have sized the wrong asset — usually too small, because the rule-based controller leaves arbitrage value uncaptured and makes additional capacity look less valuable than it is.

The three dispatch strategies compared

Almost every commercial controller in the field is one of three design families. They differ in how much they assume about the future.

Rule-based priority dispatch

A deterministic priority list — typically PV, then wind, then battery, then grid, then diesel — evaluated at each timestep. On surplus, charge the battery, then export, then curtail. On deficit, discharge the battery, then import, then start the diesel. When diesel and battery coexist, pre-emptive activation thresholds start the generator before the battery is empty, typically around 15% state of charge, and stop it once the battery is back to roughly 40%.

Rule-based dispatch has one enormous practical advantage: it maps directly to PLC code. Program a Schneider EcoStruxure, ABB Ability MGS or Siemens MGMS controller with the same priority list and thresholds and you get the same behavior. It is also predictable, which matters to operators who are accountable for a machine they cannot easily audit. Its weakness is that it cannot see a price. A threshold controller will cycle a battery on a day when the spread does not cover the wear, because it has no concept of wear.

Economic dispatch (linear programming)

At each dispatch interval, solve a linear program that minimizes total operating cost over a horizon — commonly 24 hours — subject to the physical and commercial constraints of the system. The solver returns charge, discharge, import, export, diesel output and state of charge for every step. Energy Optima uses the HiGHS solver via scipy, and re-optimizes on a configurable interval, 30 minutes by default.

Economic dispatch with perfect foresight is an upper bound on revenue, not a forecast. In practice it runs on a forecast, which is where the accuracy gap opens: a perfectly-informed LP and a real MPC controller with a real forecast are different machines, and a model that reports the former's numbers as the latter's is flattering itself.

Model-predictive control

MPC is economic dispatch run as a rolling receding horizon: optimize over the next N hours, execute only the first interval, then re-measure and re-solve. It is the family that handles forecast error honestly, because it corrects course instead of committing to a 24-hour plan made with yesterday's weather.

Both economic LP and MPC are usually implemented with a terminal value on stored energy. Without one, the optimizer drains the battery at the end of every horizon, because the last hour of the horizon has no tomorrow and free energy looks optimal. Assigning stored energy a value — typically derived from the cost of the next-best alternative source — removes that artifact.

How the optimizer decides: objective and constraints

An optimizer is an objective function plus a constraint set. Everything else is plumbing. Being explicit about both is what separates a model you can defend to an investment committee from one you cannot.

The objective function

For a cost-minimizing system the objective is, in its essentials:

minimize   Σ_t [ import(t)·price(t) − export(t)·export_price(t) + diesel(t)·fuel_cost + throughput(t)·wear_cost + unmet(t)·penalty − SOC(T)·terminal_value ]

Every term is a decision. The unmet-load penalty should be set high enough that it is only ever selected as a last resort, because a model that sheds load to save money is telling you its penalty is too low, not that the load is optional. The export term can be negative — a negative price is a real feature of several European markets in high-solar hours, and an optimizer that clips prices at zero will import energy it should have been paid to absorb.

For a revenue-maximizing merchant asset the sign structure flips: maximize arbitrage and ancillary revenue minus operating cost, subject to the same constraints. That formulation is where the degradation problem becomes acute, because there is no compensating cost term to push back.

The constraint set

  • State-of-charge bounds. Not 0–100%. Usable SOC is bounded, typically 5–95%, and the upper bound matters more than most people expect: the last few percent of charge happen at reduced current and reduced efficiency, so pushing to 100% buys little energy and costs calendar life.
  • Power limits, state-dependent. A battery cannot accept full rated power at high SOC or deliver it at low SOC. Charge and discharge capability should be functions of both SOC and state of health, not a flat nameplate number.
  • Ramp and start constraints on thermal generation. Diesel units have start delays measured in minutes and minimum stable loads. An optimizer that treats a generator as a continuous variable will produce dispatch plans no control system can execute.
  • Grid interconnection and export caps. The connection agreement is often the binding constraint in hybrid projects, and it is one of the most commonly mis-specified inputs in a feasibility study.
  • Degradation and warranty limits. Annual throughput caps, cycle limits, and temperature derating — either as hard constraints or priced in the objective.
  • SOC tracking. The state at the end of one interval must equal the state at the start of the next, adjusted by efficiency and self-discharge. This is the coupling constraint that makes the problem dynamic rather than a series of independent hours.

Why the marginal value of a cycle changes with state of health. Two things happen as a battery ages, and both push the same direction. First, the same dispatched energy moves the state of health further, because capacity has shrunk — a fixed MWh throughput becomes a larger fraction of remaining capacity. Second, round-trip efficiency falls, so more throughput is required to deliver the same energy at the meter. The result is that a cycle costs more to run in year twelve than in year one, even at an identical price spread. An optimizer with a static wear cost is structurally wrong in the later years of every project it models.

Two-panel bar chart: degradation cost per kWh of throughput and breakeven price spread required to justify cycling, for a 2-hour LFP battery at state of health from 100% down to 80%.
Figure 1: What a cycle costs as the battery ages, for a 2-hour LFP system at $320/kWh with 6,000 nameplate cycles. Top: wear cost per kWh of throughput. Bottom: the price spread a dispatch must clear before cycling pays for itself, after round-trip and PCS losses. Both rise as state of health falls. Illustrative calculation, not a benchmark — substitute your own capital cost, cycle life and efficiency data.

Using the arithmetic in Figure 1: at $320/kWh installed and 6,000 nameplate cycles, the wear cost starts at about $0.027/kWh of throughput at beginning of life and reaches roughly $0.033/kWh at 80% state of health. Converted to a price spread at the meter — double for the round trip and divide by efficiency — a cycle needs a spread of roughly €58/MWh to break even at beginning of life, rising to roughly €76/MWh at 80% SOH. A market that offers €60/MWh spreads is worth cycling in year one and not worth cycling in year fifteen, and the only way a dispatch algorithm knows the difference is if the wear term is inside the objective.

Degradation-aware dispatch

Most models apply degradation as post-processing: run the dispatch, count the cycles, then apply a fade curve to the resulting throughput. This is backwards. It computes wear as a consequence of revenue when in practice the two are reciprocal — the cost of wear is one of the reasons a dispatch decision should not be taken, and that constraint has to exist during optimization to have any effect.

The mechanism is a wear cost per kWh of throughput inside the objective:

wear_cost = capex_per_kwh / (2 × nameplate_cycles) / SOH

The division by two converts full cycles to throughput (one cycle moves energy in and out). Dividing by SOH accounts for the fact that the same throughput consumes a larger share of a smaller battery. In a simulation, the numerator and denominator can both be looked up from measured cell data rather than assumed: Energy Optima carries manufacturer-specific degradation tables organized across year, C-rate and cycles-per-day, interpolated in three dimensions, so the wear cost the optimizer sees at year twelve reflects the cells' actual measured behavior at that age and duty cycle, not a straight-line assumption.

The behavioral consequence is the part that matters and the part that surprises people:

  • A revenue-maximizing optimizer over-cycles. In a representative 100 MW / 200 MWh merchant case in a European day-ahead market, a perfect-foresight economic dispatch earned the most gross revenue of the three strategies compared — heavily outperforming a rule-based threshold controller — but also incurred the heaviest degradation and replacement cost, roughly triple the rule-based figure. Net of wear, it fell behind a degradation-aware rolling optimizer by about 11%, and the degradation-aware case beat rule-based by roughly 42% on ten-year net value.
  • The optimal merchant dispatch is not the revenue-maximizing dispatch. The degradation-aware optimizer gave up a small amount of gross revenue — on the order of 2% — to cut wear substantially. It cycles in the middle SOC band more, avoids the extremes, and moderates C-rate. That is not caution, it is arithmetic: capacity spent today cannot capture tomorrow's spread.
  • Naive degradation modeling understates the problem twice. First because it ignores the decision, and second because a linear annual fade percentage cannot represent the dependence of wear on how the battery is used. A battery cycled at 0.25C once a day and one cycled at 0.5C twice a day do not differ by a few percent of life; they can differ by a decade of usable service.

There is also an execution layer that pure optimization misses. The LP solves a linear approximation; real batteries are nonlinear, with CC-CV charging behavior, voltage sag and SOH-adjusted limits. A plan that is optimal in the linear model can be infeasible on the hardware. Closing that gap means checking the plan against a nonlinear battery model and feeding corrected limits back to the solver — iterating until the planned dispatch and the executable dispatch agree. That is the same architecture commercial MPC controllers use, and skipping it is why some simulated dispatch never happens in the field.

Choosing a strategy for your revenue stack

The right strategy follows from what the asset is paid for. It is not a maturity ladder where economic dispatch is simply "better."

  • Energy arbitrage. Economic LP or MPC, always. Arbitrage value exists only in the hour-by-hour shape of prices, so a controller without a price input leaves most of the value on the floor. Forecast quality is the binding constraint — a smoothed daily shape erases the intraday spread the asset is built to capture.
  • Demand-charge management. Economic dispatch with the correct ratchet and demand-interval structure. This is one of the few applications where a well-formulated LP reliably beats rule-based by a wide margin, because the objective is a single monthly maximum that a threshold controller cannot see coming.
  • Frequency response and ancillary services. Neither family is sufficient on its own. The dispatch has to reserve headroom for the response obligation first and then optimize around it; a pure economic optimizer will happily sell the capacity it needs to keep in reserve, and a rule-based controller will hold too much.
  • Reliability-first off-grid or weak-grid systems. Rule-based, or a hybrid where the optimizer is subordinate to hard reliability constraints. When the cost of unmet load is a blackout rather than a number in a spreadsheet, predictability outranks optimality.
  • Behind-the-meter C&I with flat tariffs. Rule-based, and do not over-invest in optimization software. If the tariff has no time structure and export is not compensated, there is no spread to optimize.

In practice most projects end up with a hybrid: a degradation-aware economic optimizer for the energy schedule, with rule-based logic retained as a supervisory layer and a hard reliability backstop. The comparison of the two design families, including where each one maps to commercial products, is covered in more detail in the dispatch strategy comparison.

What the optimizer cannot fix

Optimization is the last 10% of a project's economics, and it cannot rescue the first 90%. Five inputs determine the outcome before the solver ever runs, and none of them are improved by a better algorithm.

  • An undersized interconnection. If the grid connection caps export at a level below what the generation and storage could deliver, the optimizer's only remaining degree of freedom is curtailment. No dispatch strategy recovers energy it is not allowed to export. This is a development problem, not a modeling one.
  • A wrong tariff assumption. Rate structures with demand ratchets, power-factor penalties, time-of-use windows that shift seasonally, or export compensation that is capped in hours are routinely modeled as a single flat rate. Every one of those simplifications is a systematic bias, and several of them are optimistic.
  • A bad load profile. Synthetic load shapes built from a monthly total and an assumed daily curve produce confident, precise, wrong answers. A real 8760-hour profile — ideally measured, otherwise from a defensible sector benchmark — is worth more to the accuracy of the result than any improvement in solver sophistication.
  • A price forecast that has no shape. Averaging prices to a monthly figure mechanically deletes the intraday spread and the seasonal ramp that storage exists to exploit. Running multiple price scenarios matters more than running one central case precisely.
  • The wrong battery. Chemistry, C-rate capability, cycle life and temperature derating are procurement decisions. An optimizer can only exploit what the cells can physically do, and a battery chosen for the wrong duty cycle will underperform regardless of how it is dispatched.

These are the assumptions to interrogate first, and they are the reason a sensitivity analysis on inputs is worth more than an extra decimal place in the dispatch result. An honest model reports the limits of its own inputs alongside its output.

Frequently asked questions

What is BESS dispatch optimization?
BESS dispatch optimization is the process of choosing, at every timestep, how much a battery charges or discharges so that a stated objective is met while physical and commercial limits are respected. The objective is usually minimum electricity cost or maximum project NPV; the limits include state-of-charge bounds, C-rate, interconnection or export caps, and the cost of cycling.
Is BESS optimization the same as sizing?
No. Sizing optimization decides how much power and energy to build and is run once at design stage. Dispatch optimization decides how to operate whatever was built and runs continuously. They are coupled: the optimal size depends on the dispatch it will be run with, so sizing a battery against a fixed rule-based dispatch systematically mis-sizes projects that will actually be operated with an economic optimizer.
Does dispatch optimization account for battery degradation?
Only if the model explicitly prices cycling in the objective function. A purely revenue-maximizing optimizer will use the battery hardest because wear is free to it, which overstates project value. A degradation-aware optimizer charges a wear cost per kWh of throughput that rises as state of health falls, so it stops cycling when the spread is too thin to cover the damage.
How much does dispatch strategy change NPV?
In Energy Optima simulations the difference between rule-based and economic dispatch is typically 10–15% of lifetime project cost, and the gap between a revenue-maximizing and a degradation-aware optimizer can be similar or larger on a net basis — the revenue-maximizer captures slightly more gross revenue while spending more on replacement capacity. The result is project-specific and depends on the tariff, the battery and the market.
What inputs does a dispatch optimizer need?
Hourly generation forecasts, an hourly load profile, a tariff or price signal including demand charges and export limits, battery performance data across state of health, and any contractual or grid-code constraints. A good model is limited first by the quality of the load profile and tariff assumptions, not by the solver.

Simulate both dispatch strategies on your own project

Configure a system, run rule-based and degradation-aware economic dispatch against the same tariff and load profile, and compare lifetime cost, NPV and battery replacement timing. Free to start, no email wall.

Start Free Trial

Further reading

The same coupling matters commercially: merchant BESS revenue modeling works through the revenue-and-wear problem for a 100 MW asset.

How operating band choices change degradation in practice is covered in SOC thresholds for BESS operation.

For the financial side, see calculating IRR, NPV and payback for storage projects.