Network Pulse

← All notes

The store, table by table

Status: generated, not written. Every table and column below came out of 07-schema.R run against the store on 2026-09-08, holding two days of capture and one timetable export. Row counts move; the shapes do not. Regenerate it rather than editing it by hand.

What each field means, and which are populated, is in what comes out of BODS. This is the column list.

CAPTURED MATCHED MEASURED AGAINST parquet · positions line origin_ref origin_dep_local the only key sched_today same three columns trip_id one row per trip trip_id stop_times → stops timepoint, departure_time stop_lat, stop_lon → punctuality shape_id trips → shapes → miles, 83.2% of trips operator agency agency_noc trips.block_id 81.1% follow another chains journeys journey_code vs vehicle_journey_code — 0% match, ruled out trips.vehicle_journey_code No shared journey id exists. The three-column key stands in for one; blocks chain journeys inside the timetable alone.
A position row carries no trip id. It reaches the timetable only through line, origin stop and origin departure time together, which is why the day has to be filtered to the services that actually ran before that key is unique enough to use.

Captured

Written by the poller, one parquet file per poll into a dated folder. Not a table: every query globs the folder, which is what keeps the single writer out of the readers' way.

parquet · positions — 1,068,693 rows

One row per vehicle per poll

column type
recorded TIMESTAMP The vehicle's own RecordedAtTime
pulled_at TIMESTAMP When we fetched it. The gap between these two is the stale tail
vehicle_key VARCHAR operator + vehicle, because VehicleRef alone collides
operator VARCHAR NOC
vehicle VARCHAR
line VARCHAR Journey key
line_ref VARCHAR As published
direction VARCHAR
journey_code VARCHAR Operator's ticket-machine code. Joins nothing
block_ref VARCHAR Operator's block number. Joins nothing — see below
origin_ref VARCHAR Journey key. ATCO, joins stops.stop_id
origin_name VARCHAR
dest_ref VARCHAR
dest_name VARCHAR
origin_dep TIMESTAMP
origin_dep_local VARCHAR Journey key
dest_arr TIMESTAMP
lat DOUBLE
lon DOUBLE
bearing DOUBLE -1 is a no-value sentinel
monitored VARCHAR

The timetable, as loaded

One GTFS export, read straight in and left alone. Every column is text: a stop_id of 0345 read as a number silently drops every join it takes part in.

agency — 58 rows

One row per operator

column type
agency_id VARCHAR OP153-style
agency_name VARCHAR
agency_url VARCHAR
agency_timezone VARCHAR
agency_lang VARCHAR
agency_phone VARCHAR
agency_noc VARCHAR The only bridge to the feed's OperatorRef

routes — 1,226 rows

One row per route

column type
route_id VARCHAR
agency_id VARCHAR
route_short_name VARCHAR The line as printed on the bus
route_long_name VARCHAR
route_type VARCHAR

trips — 90,551 rows

One row per trip

column type
trip_id VARCHAR VJ + 40 hex
route_id VARCHAR
service_id VARCHAR
trip_headsign VARCHAR
direction_id VARCHAR
block_id VARCHAR 74.7% populated. The chain that predicts departures
shape_id VARCHAR 83.2% of trips
wheelchair_accessible VARCHAR Present, empty
vehicle_journey_code VARCHAR TransXChange's id. Not the feed's journey_code

stop_times — 4,161,549 rows

One row per trip and stop

column type
trip_id VARCHAR
stop_id VARCHAR
stop_sequence VARCHAR Text — cast before ordering
arrival_time VARCHAR Local service time; 24:15:00 is legal
departure_time VARCHAR
stop_headsign VARCHAR
pickup_type VARCHAR
drop_off_type VARCHAR
shape_dist_traveled VARCHAR Empty
timepoint VARCHAR 13.3% — the stops the timetable commits to

stops — 32,462 rows

One row per stop

column type
stop_id VARCHAR ATCO
stop_code VARCHAR
stop_name VARCHAR
stop_lat VARCHAR
stop_lon VARCHAR
wheelchair_boarding VARCHAR Present, empty
location_type VARCHAR
parent_station VARCHAR
platform_code VARCHAR

calendar — 209 rows

One row per service pattern

column type
service_id VARCHAR
monday … sunday VARCHAR Seven flag columns
start_date VARCHAR
end_date VARCHAR

calendar_dates — 16,822 rows

One row per service exception

column type
service_id VARCHAR
date VARCHAR
exception_type VARCHAR 1 adds a day, 2 removes one

shapes — 3,966,315 rows

One row per shape point

column type
shape_id VARCHAR
shape_pt_lat VARCHAR
shape_pt_lon VARCHAR
shape_pt_sequence VARCHAR Text — cast before ordering
shape_dist_traveled VARCHAR Empty

Derived for measurement

Built from the timetable, not from the feed. sched is the journey-level table — one row per trip, carrying the three columns the live feed is matched on.

sched — 90,551 rows

One row per trip — not per stop

column type
trip_id VARCHAR
service_id VARCHAR
direction_id VARCHAR
line VARCHAR Journey key
route_type VARCHAR
agency_id VARCHAR
agency_name VARCHAR
origin_ref VARCHAR Journey key
origin_dep_local VARCHAR Journey key

sched_today — 28,772 rows

One row per trip running today

column type
(same nine columns assched) Filtered to today's service_ids

hist_sched — 28,496 rows

One row per trip on the day being scored

column type
(same nine columns assched) Filtered to that day's service_ids

sched_today_services / active_services / hist_sched_services — 117 / 117 / 122 rows

One row per service running that day

column type
service_id VARCHAR The calendar filter, resolved once

timetable_stamp — 1 rows

One row: which export is loaded

column type
label VARCHAR
source_file VARCHAR
file_bytes BIGINT
file_modified VARCHAR
stamped_at VARCHAR
fingerprint VARCHAR Trips / stop_times / calendar range. Detects a reload without a re-stamp

Scored history

Written only for finished days. Today is never stored: a part-day filed as a whole one is exactly the number that gets quoted back at you six months later.

hist_stop_visits — 22,752 rows

One row per bus, stop and day

column type
date VARCHAR
vehicle VARCHAR
noc VARCHAR
operator VARCHAR
line VARCHAR
stop_name VARCHAR
scheduled VARCHAR
actual VARCHAR
delay_min DOUBLE
band VARCHAR
on_time INTEGER
early INTEGER
late_over_5 INTEGER

hist_journeys — 12,594 rows

One row per scheduled journey and day

column type
line VARCHAR
operator VARCHAR
noc VARCHAR
direction VARCHAR
origin VARCHAR
scheduled VARCHAR
is_first INTEGER
is_last INTEGER
status VARCHAR One of six
ran INTEGER
measurable INTEGER Only Ran and Not seen
miles DOUBLE
miles_basis VARCHAR Per journey, because it varies per journey
date VARCHAR

hist_days — 1 rows

One row per finished day

column type
date VARCHAR
weekday VARCHAR
watched_from VARCHAR
watched_to VARCHAR
watched_hours DOUBLE
pings DOUBLE
vehicles DOUBLE
stop_visits INTEGER
on_time INTEGER
early INTEGER
late_over_5 INTEGER
on_time_pct DOUBLE
early_pct DOUBLE
late_pct DOUBLE
journeys INTEGER
measurable INTEGER
ran INTEGER
delivery_pct DOUBLE
miles_operated DOUBLE
miles_lost DOUBLE
miles_not_judged DOUBLE
lost_pct DOUBLE
miles_basis VARCHAR
timetable VARCHAR Which export scored it
computed_at VARCHAR