Next free-source hunt
We check for new free data every weekday.
Datasets / Energy
gov.uk/

DESNZ UK Energy Trends Tables

Freeauth: noneOGL-UK-3.0#energy#historical-data#time-series#macro-economic#flows✓ verified Nov 1, 2026

DESNZ UK Energy Trends Tables

The UK Department for Energy Security and Net Zero publishes Energy Trends tables as Excel and OpenDocument spreadsheets covering coal, oil, gas, electricity, renewables and total energy supply and demand. Tables contain monthly, quarterly and annual periods with fuel, generation, consumption, trade, capacity and share measures; downloads need no key.

Required Attribution:

If DESNZ supplies no table-specific statement, use: "Contains public sector information licensed under the Open Government Licence v3.0."

Coverage

The collection covers the United Kingdom, with table-specific history; the checked monthly electricity production table runs from January 1997 through provisional August 2026. Monthly data is generally published two months in arrears, quarterly data one quarter in arrears, and the headline collection is issued quarterly while component table pages can update monthly.

Verdict

This is an official UK energy-balance and power-sector signal for tracking production, consumption, fuel mix, imports, exports and renewable penetration. The files provide long time series but arrive with a two-month or one-quarter lag, so they suit macro and structural analysis rather than immediate operations. Latest observations can be provisional and earlier periods can be revised when suppliers update data or estimates are replaced. Table layouts, note markers and availability flags require table-specific parsing and preservation of methodology notes.

Get the free weekly email

Free weekly email of newly verified free data. Unsubscribe by emailing us.

Use in your agent

Load UK monthly electricity trends into pandas and Parquet. Checked against the provider's documentation on Nov 1, 2026.

Raw skill file (/skills/uk-energy-trends.md)Also in our MCP server: call get_ingestion_skill with {"slug": "uk-energy-trends"}.

Access

  • No account or key; Energy Trends spreadsheets are public downloads.
  • This example parses ET 5.4 directly from XLSX ZIP/XML content and preserves the provisional flag.

Request

bash
curl -O 'https://assets.publishing.service.gov.uk/media/6ae0cba87cf9b224890467e4/ET_5.4_OCT_26.xlsx'

Format

Multi-sheet XLSX workbook with cover, contents, notes, commentary and annual, quarterly and monthly electricity tables; ET 5.4 measures TWh by fuel, supply, trade and aggregate shares.

Load into pandas and Parquet

Needs Python 3 with requests, pandas and pyarrow.

python
"""UK Energy Trends ET 5.4 monthly electricity data -> pandas -> Parquet."""
import io
import zipfile
import xml.etree.ElementTree as ET
import requests
import pandas as pd

URL = "https://assets.publishing.service.gov.uk/media/6ae0cba87cf9b224890467e4/ET_5.4_OCT_26.xlsx"
response = requests.get(URL, timeout=120)
response.raise_for_status()
ns = "{http://schemas.openxmlformats.org/spreadsheetml/2006/main}"
selected = {
    "A": "month", "D": "mpp_supply_twh", "E": "coal_twh", "G": "gas_twh",
    "H": "nuclear_twh", "J": "wind_twh", "M": "solar_twh", "N": "bioenergy_twh",
    "T": "net_imports_twh", "V": "total_available_twh", "W": "low_carbon_twh",
    "X": "renewables_twh", "Y": "fossil_fuels_twh",
}
with zipfile.ZipFile(io.BytesIO(response.content)) as book:
    strings_root = ET.fromstring(book.read("xl/sharedStrings.xml"))
    strings = ["".join(t.text or "" for t in item.iter(ns + "t")) for item in strings_root]
    rows = []
    for _, row in ET.iterparse(book.open("xl/worksheets/sheet9.xml"), events=("end",)):
        if row.tag != ns + "row" or int(row.attrib["r"]) < 8:
            continue
        record = {}
        for cell in row.findall(ns + "c"):
            column = "".join(c for c in cell.attrib["r"] if c.isalpha())
            if column not in selected:
                continue
            value_node = cell.find(ns + "v")
            if value_node is None:
                continue
            value = value_node.text
            if cell.attrib.get("t") == "s":
                value = strings[int(value)]
            record[selected[column]] = value
        if record.get("month"):
            rows.append(record)
        row.clear()
df = pd.DataFrame(rows)
df["is_provisional"] = df["month"].str.contains("provisional", case=False)
df["month"] = df["month"].str.replace(r"\s*\[provisional\]", "", regex=True)
df["month"] = pd.to_datetime(df["month"], format="%B %Y", errors="coerce")
df = df.dropna(subset=["month"])
for column in df.columns.drop(["month", "is_provisional"]):
    df[column] = pd.to_numeric(df[column], errors="coerce")
df = df.sort_values("month")
df.to_parquet("uk_energy_trends_et54.parquet", index=False)
print(len(df), "monthly observations", df["month"].min().date(), "to",
      df["month"].max().date(), "across", len(df.columns) - 2, "electricity series")

Run by us on 2026-11-01 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 356 monthly observations 1997-01-01 to 2026-08-01 across 12 electricity series

Limits

  • Rate limit: Not stated.
  • Monthly statistics are published two months in arrears and quarterly statistics one quarter in arrears.
  • History and workbook structure vary by Energy Trends table.

Quirks

  • The checked ET 5.4 workbook stores the latest month as text with a provisional marker; remove the marker only after preserving it in a separate field.
  • The marker [x] means data is unavailable and should become a missing value rather than zero.
  • Workbook sheet positions and asset URLs can change with each release, so discover the latest file from the table page before scheduling ingestion.

Terms and attribution

  • GOV.UK content is OGL v3.0 except where otherwise stated.
  • Acknowledge the source and link to the licence where possible.

Sources

Information and education only. Not financial, investment, legal or tax advice. Listings can be inaccurate, incomplete or out of date and are provided "as is". Free tiers, limits and licenses belong to each provider and can change, so check the provider's own terms before you rely on them. Terms & Disclaimer