ORR rail statistics data portal
ORR rail statistics data portal
The Office of Rail and Road portal publishes Great Britain rail statistics for passenger and freight usage, performance, fares, finance, safety, accessibility, infrastructure, environment and stations. Periodic tables can be downloaded as CSV, JSON or XLSX and expose time period, operator, route, region, commodity or performance measures depending on the table; no key is required.
Required Attribution:
Contains public sector information licensed under the Open Government Licence v3.0.
Coverage
Coverage is Great Britain, with history and update cadence varying by table. The freight section combines four-weekly operational tables, quarterly releases and annual series; its periodic tables can take up to 15 working days after period end, and the checked commodity table ran from period 1 of 2019-20 through period 6 of 2026-27.
Verdict
This portal supplies rail demand, freight-flow, punctuality, cancellation, fare, finance, asset and safety signals across Great Britain. Periodic freight and passenger-performance tables can surface corridor or commodity changes before annual aggregates. Cadence and history differ by table, and operational tables may arrive up to 15 working days after a rail period ends. Some source data comes from Network Rail and validation queries can delay publication, so preserve table metadata and release dates alongside observations.
Get the free weekly email
Free weekly email of newly verified free data. Unsubscribe by emailing us.
By entering your email and clicking Subscribe, you agree to receive the Signal Lab weekly email from Quantum Data Technologies Ltd., 3200-650 West Georgia Street, Vancouver, BC V6B 4P7, Canada (signal-lab@qdt.ai). You can unsubscribe at any time: reply "unsubscribe" to any email or write to signal-lab@qdt.ai. See our Privacy Policy.
Use in your agent
Load an ORR periodic freight table into Parquet. Checked against the provider's documentation on Nov 1, 2026.
Access
- No account or key. The table rows are embedded in the public HTML page.
- The page also offers client-side CSV, JSON and XLSX downloads.
Request
curl 'https://dataportal.orr.gov.uk/statistics/usage/freight-rail-usage-and-performance/table-1314-freight-moved-by-commodity-periodic-1/'Format
HTML table with one row per rail period and 13 commodity columns measured in million net tonne kilometres.
Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
"""ORR periodic freight-by-commodity table -> pandas -> Parquet. No key."""
from html.parser import HTMLParser
import requests
import pandas as pd
URL = "https://dataportal.orr.gov.uk/statistics/usage/freight-rail-usage-and-performance/table-1314-freight-moved-by-commodity-periodic-1/"
class TableParser(HTMLParser):
def __init__(self):
super().__init__()
self.in_table = False
self.in_cell = False
self.row = []
self.rows = []
self.text = []
def handle_starttag(self, tag, attrs):
attrs = dict(attrs)
if tag == "table" and attrs.get("id") == "reportTable":
self.in_table = True
elif self.in_table and tag == "tr":
self.row = []
elif self.in_table and tag in {"th", "td"}:
self.in_cell = True
self.text = []
def handle_data(self, data):
if self.in_cell:
self.text.append(data)
def handle_endtag(self, tag):
if self.in_table and tag in {"th", "td"}:
self.row.append(" ".join("".join(self.text).split()))
self.in_cell = False
elif self.in_table and tag == "tr" and self.row:
self.rows.append(self.row)
elif self.in_table and tag == "table":
self.in_table = False
r = requests.get(URL, timeout=60)
r.raise_for_status()
parser = TableParser()
parser.feed(r.text)
df = pd.DataFrame(parser.rows[1:], columns=parser.rows[0])
df.to_parquet("orr_freight_moved_by_commodity.parquet", index=False)
print(len(df), "rows", df["Time period"].iloc[0], "to", df["Time period"].iloc[-1],
len(df.columns) - 1, "commodity columns")Run by us on 2026-11-01 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 97 rows Apr 2019 to Mar 2020 (Period 01) to Apr 2026 to Mar 2027 (Period 06) 13 commodity columns
Limits
- Rate limit: Not stated.
- The example covers one periodic freight table, not the portal's full collection.
- ORR says periodic freight tables can take up to 15 working days after period end to update.
Quirks
- The CSV, JSON and XLSX buttons generate downloads in the browser; the example parses the same embedded HTML table.
- Rail periods are four-week reporting periods and are labeled within a financial year, not calendar months.
- Commodity columns include their unit in the header; retain the header text or map units separately.
Terms and attribution
- ORR Crown-copyright material may be reused under OGL v3 free of charge.
- Logos and identified third-party material are excluded from that permission.
Sources
- https://dataportal.orr.gov.uk/statistics/usage/freight-rail-usage-and-performance/: “Quarterly and periodic (4-weekly) statistics on the volume of freight transported by rail and the punctuality of those services.”
- https://dataportal.orr.gov.uk/statistics/usage/freight-rail-usage-and-performance/: “it can take up to 15 working days after period end for the table to be updated.”
- https://dataportal.orr.gov.uk/statistics/usage/freight-rail-usage-and-performance/table-1314-freight-moved-by-commodity-periodic-1/: “Download CSV”
- https://www.orr.gov.uk/terms-and-conditions: “All content is available under the Open Government Licence v3.0, except where otherwise stated”
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