Capacity Factor Explained
On this page
Problem statement
A solar farm in Toledo and a wind farm in western Jutland are both described by their capacity β 50 MW, say β and that number says almost nothing about how much energy either produces. The solar farm will deliver the equivalent of 50 MW for about four and a half hours a day. The wind farm, in a good year, more than twice that.
Capacity factor is the number that connects the two: the energy actually produced divided by what the nameplate would have produced running flat out all year. It is the most quoted and most misquoted figure in renewable siting, because it has a denominator that changes with who is reporting it and a numerator that can be gross or net.
Quick answer
capacity factor = energy produced (kWh) / (rated power (kW) Γ hours in the period)
For solar the same idea is often expressed as specific yield (kWh per kWp per year) or full-load hours (kWh Γ· kW). All three carry the same information:
import requests
def pvgis_yield(lat, lon, **kw):
"""Annual AC energy for 1 kWp from PVGIS, with 14% system losses."""
j = requests.get("https://re.jrc.ec.europa.eu/api/v5_3/PVcalc", params={
"lat": lat, "lon": lon, "peakpower": 1, "loss": 14,
"outputformat": "json", **kw}, timeout=120).json()
return j["outputs"]["totals"]["fixed"]["E_y"], j["inputs"]["mounting_system"]["fixed"]
for name, (lat, lon) in {"Toledo": (39.86, -4.02), "Hamburg": (53.55, 9.99)}.items():
e, mount = pvgis_yield(lat, lon, optimalangles=1)
print(f"{name:<8} {e:,.0f} kWh/kWp = {e:,.0f} full-load hours "
f"= capacity factor {e / 8760:.1%} (tilt {mount['slope']['value']}Β°)")
Toledo 1,633 kWh/kWp = 1,633 full-load hours = capacity factor 18.6% (tilt 36Β°)
Hamburg 990 kWh/kWp = 990 full-load hours = capacity factor 11.3% (tilt 40Β°)
Specific yield divided by 8,760 is the capacity factor. A Toledo panel is a 19% machine; a Hamburg panel an 11% one.
Fix the denominator and numerator, use full years
1. Fix the denominator
Solar capacity is quoted in DC (kWp, the module rating) or AC (the inverter rating). Plants are built with more DC than AC β a ratio of 1.2 to 1.4 is normal β so the same plant has a higher AC capacity factor than DC capacity factor. Say which.
2. Fix the numerator
Gross energy is what the resource and the power curve imply. Net energy subtracts wake losses, availability, curtailment, electrical losses and soiling. The gap is typically 10β20% for wind, and a gross figure presented as a net one is the most common way a site looks better than it is.
3. Use a full year, or better, many
A capacity factor for one month is a statement about that month, and one year is not much better. Over 2005β2023 (Example 4), the Jutland turbine's annual energy ranged from 15% below its mean to 10% above; the Toledo panel's stayed within 5% either side. Siting studies use long-term averages and report the spread.
4. Compare like with like
Solar capacity factors are low because the sun sets, not because the technology is poor. Comparing a solar capacity factor with a wind one says which resource is steadier, not which project is better.
5. Do not read capacity factor as land efficiency
A wind farm with a 40% capacity factor uses far more land per MWh than a solar farm with 19%, because turbines are spaced many rotor diameters apart. Energy per kmΒ² is a different number with its own guide.
6. Keep the hours honest
8,760 hours in a normal year, 8,784 in a leap year. Hourly data with gaps or duplicated daylight-saving hours changes the denominator without anybody noticing.
Tilt, DC versus AC, and a wind turbine
Example 1 β tilt changes the yield, not the rating
print(f"{'site':<9}{'flat':>8}{'optimal':>9}{'gain':>7}")
for name, (lat, lon) in {"Toledo": (39.86, -4.02), "Hamburg": (53.55, 9.99)}.items():
flat, _ = pvgis_yield(lat, lon, angle=0, aspect=0)
best, _ = pvgis_yield(lat, lon, optimalangles=1)
print(f"{name:<9}{flat / 8760:>8.1%}{best / 8760:>9.1%}{best / flat - 1:>7.0%}")
site flat optimal gain
Toledo 15.8% 18.6% 18%
Hamburg 9.4% 11.3% 20%
The same kilowatt of modules is a 16% or a 19% machine in Toledo depending only on how it is mounted. A capacity factor is a property of the plant design as much as of the place.
Example 2 β DC or AC capacity
import numpy as np, pandas as pd, pvlib
j = requests.get("https://re.jrc.ec.europa.eu/api/v5_3/seriescalc", params={
"lat": 39.86, "lon": -4.02, "startyear": 2023, "endyear": 2023,
"angle": 36, "aspect": 0, "components": 1, "outputformat": "json"},
timeout=120).json()
h = pd.DataFrame(j["outputs"]["hourly"])
poa = h["Gb(i)"] + h["Gd(i)"] + h["Gr(i)"]
cell = pvlib.temperature.faiman(poa, h["T2m"], h["WS10m"])
dc_kw = 1.0
dc = pvlib.pvsystem.pvwatts_dc(poa, cell, pdc0=dc_kw, gamma_pdc=-0.004) * 0.9
for ratio in (1.0, 1.2, 1.4):
ac_kw = dc_kw / ratio
ac = pvlib.inverter.pvwatts(dc, pdc0=ac_kw / 0.96, eta_inv_nom=0.96)
e = ac.clip(lower=0).sum()
print(f"DC/AC {ratio:.1f}: {e:,.0f} kWh, CF on DC {e / (dc_kw * 8760):.1%}, "
f"CF on AC {e / (ac_kw * 8760):.1%}, clipped {1 - e / (dc * 0.96).sum():.1%}")
DC/AC 1.0: 1,774 kWh, CF on DC 20.2%, CF on AC 20.2%, clipped 0.2%
DC/AC 1.2: 1,771 kWh, CF on DC 20.2%, CF on AC 24.3%, clipped 0.3%
DC/AC 1.4: 1,728 kWh, CF on DC 19.7%, CF on AC 27.6%, clipped 2.7%
The energy barely moves β 2.7% is clipped at a ratio of 1.4, and the 0.2% at 1.0 is the inverter's part-load efficiency, not clipping β while the capacity factor on the inverter rating climbs from 20% to 28%. A plant quoted at 27.6% on AC and one quoted at 19.7% on DC can be the same plant.
Example 3 β the same idea for a wind turbine
from windpowerlib import WindTurbine
turbine = WindTurbine(turbine_type="V126/3450", hub_height=117)
curve = turbine.power_curve
w = requests.get("https://archive-api.open-meteo.com/v1/archive", params={
"latitude": 56.09, "longitude": 8.24,
"start_date": "2023-01-01", "end_date": "2023-12-31",
"hourly": "wind_speed_100m", "wind_speed_unit": "ms",
"timezone": "UTC"}, timeout=120).json()
v100 = np.array(w["hourly"]["wind_speed_100m"])
v_hub = v100 * (117 / 100) ** 0.18 # shear from 100 m to hub height
power = np.interp(v_hub, curve.wind_speed, curve.value)
gross = power.sum() / 1e6
print(f"hours: {len(v100):,}, mean hub-height speed {v_hub.mean():.1f} m/s")
print(f"gross: {gross:,.0f} MWh, capacity factor {gross / (3.45 * len(v100)):.1%}")
for losses in (0.10, 0.15, 0.20):
print(f" net with {losses:.0%} losses: {gross * (1 - losses) / (3.45 * len(v100)):.1%}")
hours: 8,760, mean hub-height speed 8.6 m/s
gross: 16,717 MWh, capacity factor 55.3%
net with 10% losses: 49.8%
net with 15% losses: 47.0%
net with 20% losses: 44.2%
The gross figure is what the wind and the power curve imply at one grid cell. Every published wind capacity factor worth quoting is net, and the difference is larger than the difference between most candidate sites.
Example 4 β one year is not the climate
w = requests.get("https://archive-api.open-meteo.com/v1/archive", params={
"latitude": 56.09, "longitude": 8.24,
"start_date": "2005-01-01", "end_date": "2023-12-31",
"hourly": "wind_speed_100m", "wind_speed_unit": "ms",
"timezone": "UTC"}, timeout=300).json()
v = pd.Series(w["hourly"]["wind_speed_100m"], index=pd.to_datetime(w["hourly"]["time"]))
p = pd.Series(np.interp(v * (117 / 100) ** 0.18, curve.wind_speed, curve.value), index=v.index)
wind = p.groupby(p.index.year).sum() / 1e6
j = requests.get("https://re.jrc.ec.europa.eu/api/v5_3/seriescalc", params={
"lat": 39.86, "lon": -4.02, "startyear": 2005, "endyear": 2023,
"pvcalculation": 1, "peakpower": 1, "loss": 14, "angle": 36, "aspect": 0,
"outputformat": "json"}, timeout=300).json()
pv = pd.DataFrame(j["outputs"]["hourly"])
pv.index = pd.to_datetime(pv["time"], format="%Y%m%d:%H%M")
solar = pv["P"].groupby(pv.index.year).sum() / 1e3
for name, yearly in (("Jutland wind, MWh", wind), ("Toledo PV, kWh/kWp", solar)):
dev = yearly / yearly.mean() - 1
print(f"{name:<20} mean {yearly.mean():8,.0f} worst {dev.min():+.1%} "
f"({dev.idxmin()}) best {dev.max():+.1%} ({dev.idxmax()}) sd {yearly.std() / yearly.mean():.1%}")
Jutland wind, MWh mean 18,278 worst -14.8% (2021) best +9.8% (2015) sd 6.2%
Toledo PV, kWh/kWp mean 1,625 worst -4.8% (2020) best +4.5% (2005) sd 3.0%
The 2023 wind year used in Example 3 is one draw from that spread: its 16,717 MWh is 8.5% below the 19-year mean of 18,278, so the 55.3% gross capacity factor understates this site's long run. Picking 2015 instead would have overstated it by nearly 10% β as much as the gap between gross and net.
Why solar capacity factors stay low
Why solar capacity factors are capped low
At the equator on a perfectly clear day, a fixed panel produces near its rating for a few hours around noon and nothing at night. The theoretical ceiling for a fixed panel is around 30%; real sites in the sunniest deserts reach the mid-20s. A 19% capacity factor in central Spain is very good, not mediocre.
Why oversizing the DC side is normal
Inverters are expensive and modules are cheap. A plant with 1.3 kW of modules per kW of inverter clips a few percent of its energy at midday in summer and produces more in every other hour. That is why AC capacity factors are the ones grid operators care about, and DC ones the ones module sellers quote.
Why low specific power makes wind capacity factors high
The V126-3.45 has 3.45 MW on a 126 m rotor: 277 W per mΒ² of swept area. Turbines built for low wind sites put a small generator on a big rotor, so they reach rated power at lower speeds and spend more of the year there. Their capacity factor goes up and their energy per MW of generator goes up; their energy per mΒ² of rotor does not.
Degradation, curtailment and hybrid plants
- Degradation: modules lose around 0.5% of output per year, so a lifetime capacity factor is below the first-year one.
- Curtailment is energy the plant could have produced but was told not to; include it in the gross figure and exclude it from the net.
- Leap years have 8,784 hours.
- Hybrid plants sharing one grid connection need a capacity factor on the connection, not on either technology.
- Monthly capacity factors are useful for seasonal matching, not for siting.
Internal links
- Solar irradiance explained β the resource behind the solar numbers
- Wind resource explained β why wind capacity factor is so sensitive to speed
- How to model PV output with pvlib β building the energy from weather
- How to estimate wind energy with a Weibull distribution β the wind version in full
- Power density and land use explained β energy per kmΒ², a different question
- PV yield off by a factor β when the units break the number
FAQ
What is a capacity factor?
The energy a plant produced over a period divided by the energy it would have produced running at rated power for the whole period.
What is a good capacity factor for solar?
Fixed-tilt PV ranges from about 10% in northern Europe to the mid-20s in the sunniest deserts. Trackers add several points.
What is the difference between specific yield and capacity factor?
Specific yield is kWh per kWp per year. Divide it by 8,760 to get the capacity factor on a DC basis.
Why do DC and AC capacity factors differ?
Plants have more module capacity than inverter capacity. The same energy divided by the smaller AC rating gives a larger number.
Is a higher capacity factor always better?
No. It measures how steadily a plant runs relative to its rating, not how much energy it produces per euro or per kmΒ².
What losses turn gross into net wind output?
Wakes from other turbines, downtime, electrical losses, icing, curtailment and blade degradation β together typically 10β20%.