> ## Documentation Index
> Fetch the complete documentation index at: https://docs.transitionzero.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Unit commitment

> How unit commitment models the start-up, shut-down, and minimum run-time behaviour of thermal generators in dispatch scenarios.

# Summary

Unit commitment (UC) captures the fact that thermal power plants cannot be switched on and off freely. Starting a unit has a cost, and once running, a plant must typically stay on, above a minimum output, for a minimum period before it can shut down again. Without UC, a dispatch model can turn a coal plant fully on and off every hour at no cost, which overstates the flexibility of a thermal fleet and understates the value of storage and flexible generation.

To use unit commitment, mark thermal technologies as **committable**. The model then tracks a binary on/off (commitment) status for each committable unit at every hour, and accounts for start-up costs, shut-down costs, and minimum up/down times.

<Info>
  Unit commitment applies to [single-year dispatch (PyPSA)](/methodology/model-frameworks) scenarios. Marking any technology as committable turns the problem into a mixed-integer linear program (MILP). This is more realistic, but slower to solve than a linear dispatch (LP).
</Info>

# When the model uses unit commitment

Unit commitment is opt-in per technology:

* If **no** technology is committable, the scenario solves as a linear dispatch (LP).
* If **any** technology is committable, the scenario solves as a MILP, with commitment decisions co-optimised alongside dispatch.

See [Model frameworks](/methodology/model-frameworks) for the distinction between dispatch and capacity expansion.

# Setting up unit commitment

<Tip>
  **Set up unit commitment with AMP.** Ask [AMP](/platform/amp-ai-assistant) to duplicate your dispatch scenario and enable unit commitment on the thermal technologies. It will present the result for your review before you run it. If you also need capacity expansion first, ask AMP to soft-link a solved capacity-expansion scenario (see [soft-linking with AMP](/methodology/model-frameworks#soft-linking)).
</Tip>

<Steps>
  <Step title="Start from a dispatch scenario">
    Create or [duplicate](/platform/editing-scenarios#duplicating-a-scenario) a **draft** single-year dispatch scenario for the year and country you want to study. Only draft scenarios can be edited. If you also want to optimise capacities, do that first in a separate capacity-expansion run (see [Unit commitment and capacity expansion](#unit-commitment-and-capacity-expansion) below).
  </Step>

  <Step title="Enable unit commitment">
    Using the [inputs grid CSV template](/platform/editing-scenarios#customising-model-inputs), set **Committable** to `1` for each technology you want to commit (see [valid technologies](#valid-technologies) below), then set its Start-up cost, Shut-down cost, Minimum up time, and Minimum down time. Optionally set Up time before / Down time before to describe the unit's state immediately before the modelled horizon.
  </Step>

  <Step title="Check the minimum stable generation (optional)">
    Each valid technology has a default Minimum stable generation, so enabling `Committable` is enough for unit commitment to take effect. Override it where you have better data for a technology (see [Minimum stable generation](#minimum-stable-generation) below).
  </Step>

  <Step title="Confirm capacity is fixed">
    Check each committable technology is **not** capacity-expandable (Maximum additional capacity set to `0`). See [Unit commitment and capacity expansion](#unit-commitment-and-capacity-expansion) below.
  </Step>

  <Step title="Run and compare">
    Solve the scenario, then [compare](/platform/viewing-results#comparing-and-interrogating-results) it against the same scenario with `Committable` off (the LP equivalent). The unit-commitment run should show fewer, longer thermal on/off cycles and the associated start-up costs.
  </Step>
</Steps>

# Parameters

`Committable` is the master switch and is off by default. The other seven parameters are only applied to a technology once it is committable.

| Parameter | Unit | What it controls |
| :- | :- | :- |
| Committable | — | Master switch: enables the on/off commitment status for the technology |
| Minimum stable generation | fraction of capacity | Minimum output when the unit is committed (see [Minimum stable generation](#minimum-stable-generation)) |
| Start-up cost | USD/MW | Cost incurred each time the unit starts up |
| Shut-down cost | USD/MW | Cost incurred each time the unit shuts down |
| Minimum up time | hours | Minimum hours the unit must stay online once started |
| Minimum down time | hours | Minimum hours the unit must stay offline once shut down |
| Up time before | hours | Hours the unit had already been running immediately before the model horizon |
| Down time before | hours | Hours the unit had already been offline immediately before the model horizon |

<Info>
  Start-up and shut-down costs are entered **per MW of the unit's capacity** (USD/MW); the model converts them to an absolute cost per start using the unit's capacity. Times are entered in **whole hours**.
</Info>

<Warning>
  If Up time before isn't set, the unit is assumed to have been online for one hour before the horizon. With a Minimum up time set, this holds the unit on for the first hours of the horizon (the Minimum up time minus one hour). If you set Down time before, also set Up time before to `0`; otherwise the unit is held both on and off at the start, and the scenario is infeasible.
</Warning>

<Warning>
  Run unit-commitment scenarios at **hourly ([high](/methodology/model-resolution#hourly-detail)) temporal resolution**. The minimum up/down times (in hours) and the per-start costs are only represented accurately when each timestep is one hour; at coarser time-slice resolutions they are inaccurate.
</Warning>

# Valid technologies

Unit commitment is meaningful only for generators that have significant start-up costs and minimum run times. It can be enabled for four technology groups, including their variants:

* **Thermal** — coal, gas and oil plants
* **Bioenergy** — including biomass and biogas
* **Carbon capture and storage**
* **Nuclear** — often run as must-run in practice; see [Interaction with Minimum hourly utilisation](#interaction-with-minimum-hourly-utilisation) for how to keep a unit running

See the [technology directory](/platform/technologies#technology-directory) for the variants in each group.

Renewables, hydro, storage, and network technologies (transmission, interconnection) cannot use unit commitment. Their operation is limited by other factors, such as weather, reservoir levels and state of charge.

# Minimum stable generation

**[Minimum stable generation](/platform/input-types#minimum-stable-generation)** is the lowest output a committable unit can run at, as a proportion of its capacity. It is a single value per year, and is only applied when the technology is committable. Each valid technology has a default value, so enabling `Committable` is enough for unit commitment to take effect. Override it where you have better data.

In practice, unit commitment only changes the dispatch when a committable unit has a minimum output above zero:

* **Without** unit commitment, a minimum output is a hard floor the plant must meet in every hour.
* **With** unit commitment, the floor only applies *when the unit is committed*: the plant can either run at or above it, or shut down entirely.

If a committable unit's minimum output is 0 (Minimum stable generation is 0 and Minimum hourly utilisation isn't set), it can stay committed at zero output at no cost, so the model has no reason to shut it down: no start-up or shut-down events occur, and enabling `Committable` only makes the model slower (a MILP) without changing the dispatch.

## Interaction with Minimum hourly utilisation

[Minimum hourly utilisation](/platform/input-types#minimum-hourly-utilisation) sets a minimum output for individual hours. Where both are set for a technology, Minimum hourly utilisation takes precedence in those hours and Minimum stable generation applies in the rest. For a committable technology, both behave the same way: each sets the minimum output *when the unit is committed*.

<Warning>
  Under unit commitment, neither parameter can force a unit to run. Both only apply in hours where the model has chosen to commit the unit, and the model can always shut it down instead. In particular:

  * Fixing a technology's output to historical hourly levels with Minimum hourly utilisation only holds if the technology is **not** committable.
  * To keep a unit running in every hour (must-run), leave it non-committable and set its Minimum hourly utilisation.
  * To guarantee a unit produces a minimum amount of energy over the year, use [Minimum annual utilisation](/platform/input-types#minimum-annual-utilisation). The model then chooses which hours to run it.
</Warning>

# Unit commitment and capacity expansion

A committable technology must have a **fixed** capacity: it cannot also be capacity-expandable in the same scenario. (Start-up costs are applied per MW of the unit's capacity, which is only well-defined when that capacity is fixed.) If a technology is both committable and capacity-expandable, the run fails with an error.

To study unit commitment on a system whose capacities you also want to optimise, use the two-run [soft-linking](/methodology/model-frameworks#soft-linking) workflow:

1. Run a capacity-expansion scenario (OSeMOSYS, or PyPSA with capacity expansion) to determine the capacity mix.
2. Create a dispatch scenario for the year of interest with those capacities fixed (set [Maximum additional capacity](/platform/input-types#maximum-additional-capacity) to 0), and enable unit commitment there.

See [Setting up unit commitment](#setting-up-unit-commitment) above. AMP can run this workflow for you.

# Interpreting the results

For every committable unit, a unit-commitment scenario reports:

* **Unit commitment status** — the binary on/off state of the unit in each hour. Note this is *commitment*, not output: a committed unit can still produce zero if its minimum output is 0.
* **Start-up and shut-down events** — where the status switches on (start-up) or off (shut-down).
* **Start-up and shut-down costs** — the total cost of those events, reported separately and already included in the total system cost.

See [Viewing results](/platform/viewing-results#unit-commitment-results) for where to find these outputs. [AMP](/platform/amp-ai-assistant) can also help diagnose an infeasible unit-commitment run.

# Performance

Because unit commitment makes the model a MILP, solve times are longer than for the equivalent LP dispatch, and scale with the number of committable units and the number of hours. Very large unit-commitment scenarios may exceed platform size limits or run-time limits.

<Warning>
  If the solver does not find an optimal solution within the time limit, the run **fails** rather than returning a usable near-optimal result. If this happens, try reducing the number of committable technologies or nodes. See [Run statuses](/platform/run-statuses) for what to do next.
</Warning>

# Common infeasibility causes

* **A unit held on or off at the start of the horizon** — Up time before and Down time before set the unit's state before the horizon, and a Minimum up or down time then holds it in that state for the first hours. The scenario is infeasible if this conflicts with demand, or if both are set so that the unit is held on and off at once (see [Parameters](#parameters)).
* **Conflicting operational constraints** — for example a Minimum annual utilisation that forces a committable unit to run in a way its start-up/shut-down and minimum-time constraints cannot satisfy. Review annual utilisation constraints on committable technologies when enabling unit commitment.

See [Infeasibilities](/platform/infeasibilities) for how to diagnose these.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.