Skip to content
Docs

Our subway collector

Since 2026-10-04 we record subway departures straight from the MTA: the SubwayJournal Durable Object polls the eight subway GTFS-Realtime feeds every 10 s and streams “train left station” events into subway_stop_events. A departure is the feed time of the first snapshot in which a stop has dropped off its trip, the same idea as the archive’s marked_past.

Window: 12:33 to 04:49 EDT, when both were running.

Their departures we also have (same trip + stop, within 5 min)99.0% (96,606 of 97,606)
Our time minus theirsmedian 0 s; middle half 0 to +3 s; 99.4% within 15 s
Ours not in theirs3,907 departures (~4%), plus 6,055 trip_ended rows
Hour by hoursteady, no gaps

So for new data we no longer need the archive. It stays our source for April 2021 – October 2026 history.

  • Use the last departure per trip + stop. The feed sometimes drops a stop and re-adds it, so 3% of trip-stops have 2+ departed events (a few stuck trips have hundreds). The last one matches the archive; the first can be minutes early.
  • trip_ended rows are stops still listed when a whole trip vanished from the feed; their time is when the trip was last seen. Leave them out of run-time analysis.
  • departed_at is UTC but stored without a zone. In DuckDB use departed_at AT TIME ZONE 'UTC' to get a proper timestamp before converting to New York time. (Forgetting this shifted a first comparison by 4 hours.)
  • If the Durable Object restarts, the first poll after it rebuilds state and emits nothing, so a restart can lose a few seconds of departures.