How to Create a Timetable from GTFS
GTFS contains the scheduled arrival and departure times for a transit system, but opening a GTFS feed does not give you a traditional timetable.
Instead, the information needed to build a timetable is spread across several interconnected files. Turning those files into something riders or staff can easily read requires combining routes, trips, stops, service calendars, and thousands of individual stop times.
Here's how that process works.
Where are schedules stored in GTFS?
The most important file is stop_times.txt.
Each row in stop_times.txt represents a stop served by a particular trip and can include its scheduled arrival and departure time. The file also defines the order in which stops are served.
But stop_times.txt is only one part of the timetable.
To understand the schedule, you also need:
- routes.txt
- Identifies the rider-facing route.
- trips.txt
- Defines the individual trips operated on that route and connects them with a
service_id. - stops.txt
- Provides the names and identifiers of the stops in the timetable.
- calendar.txt
- Defines the regular days of the week on which a service pattern operates.
- calendar_dates.txt
- Adds or removes service on specific dates, including holidays and other exceptions.
Together, these files tell you where a trip goes, when it reaches each stop, and when that trip actually operates.
Step 1: Select a route
A timetable normally represents one route at a time.
The route_id in routes.txt connects to trips in trips.txt. Those trips can then be matched with their records in stop_times.txt.
This gives you the pool of trips that could appear in the timetable.
Step 2: Separate the directions
Most routes operate in two directions.
GTFS can use fields such as direction_id, trip headsigns, stop sequences, and route geometry to distinguish these trips.
A useful timetable typically separates the directions rather than mixing every trip into a single table.
Step 3: Determine when each trip operates
Not every trip necessarily operates every day.
The service_id assigned to a trip connects it with the GTFS service calendar.
For example, one set of trips might operate Monday through Friday, another on Saturday, and another on Sunday.
But service patterns can be more complicated than that. A route might have:
- Monday-only service
- Tuesday through Friday service
- School-day trips
- Seasonal service
- Holiday schedules
- Trips that operate only on specific dates
This is why generating a timetable based on the actual GTFS calendar is more reliable than simply assuming every route has Weekday, Saturday, and Sunday schedules.
Step 4: Select the stops to show
A long bus route might serve dozens of stops.
Putting every stop into a traditional timetable can make the schedule too wide to read, particularly on a phone or printed page.
Transit agencies often use selected timepoints instead.
Depending on the feed and the intended timetable, you may need to determine which stops provide the most useful reference points for riders.
Step 5: Build the timetable
Once the trips, service pattern, direction, stops, and stop times are known, the data can be arranged into a familiar table.
Stops become columns and individual trips become rows:
| Trip | Transit Center | Main & 3rd | Hospital | Downtown |
|---|---|---|---|---|
| 1 | 6:00 AM | 6:12 AM | 6:25 AM | 6:38 AM |
| 2 | 6:30 AM | 6:42 AM | 6:55 AM | 7:08 AM |
| 3 | 7:00 AM | 7:12 AM | 7:25 AM | 7:38 AM |
The concept is simple. Getting there from raw GTFS is the complicated part.
A real feed may contain thousands of trips and hundreds of thousands of stop-time records, all linked through IDs rather than rider-facing names.
Generate a timetable automatically
If you only need the finished timetable, there is no reason to manually join all of these files.
The free RoutePress GTFS Timetable Generator reads the relationships in your feed and turns them into an easy-to-read schedule automatically.
Upload your GTFS ZIP, select a route, and generate a timetable directly from the schedule data your agency already maintains.