GTFS playbook: Using static with realtime

To ensure continued service and accurate data is served to Google Transit users, General Transit Feed Specification (GTFS) modeling is required. GTFS modeling refers to designing static and realtime (RT) feeds to work together to convey ground reality. Learn more about the General Transit Feed Specification.

This article provides a playbook to help you handle GTFS options based on your entity.

How it works

Here are some important basics about GTFS modeling:

  • GTFS Static is for premeditated schedule and transit design. Static can be updated at a minimum of 2 days in advance, but ideally a week ahead. There’s no guarantee that updating your feed 2 days in advance will show up in your live data. Any change in a shorter timeframe is not possible, though some changes are possible in RT. It’s worth noting, however, that RT is not a modeling tool.
     
  • GTFS Realtime is designed to provide realtime status over static data. RT works best for sending service alerts (no service, delays, etc.) to Transit users. RT also helps communicate delays through positions and updates for trips or stops predefined in static. 
     
  • While there are workarounds to activate and deactivate trips in GTFS, it’s limited in that addition of undefined services (shape, stop sequence, stop times, route) in under 2 days (i.e. in realtime) is not feasible. The addition of services takes 2–7+ days due to a human review process for conflicting or “suspicious” edits.
     
  • For all changes, use feed_info.txt to pre-determine (2–7+ days in advance) when static changes go live to be consistent with your realtime feeds. Useful fields: feed_start_date and feed_end_date
Temporary re-routing and schedule definitions are currently beyond the scope of RT.

Possible alterations for static and realtime

Various transit changes occur within ground transportation services, including different durations, levels of urgency, and type of entity. We provide an overview of  “sudden changes” (realtime) and planned changes (static) in schedules below:

Timeframe Entity modified Change type
  • Static (> 2–7 days in advance)
  • Realtime (30s–48 hours)
  • Shape
  • Stop
  • Stop time
  • Schedule / Service
  • Trip
  • Route
  • Add
  • Modify
  • Delete

 

Possibilities listed by entity

Overall: 

  Static (2–7+ days) Realtime (~1 minute)
Add Most changes are possible and straightforward. In general, this isn't possible unless adding to an existing frequency with schedule_relationship.
Delete Significant deletions get flagged as suspicious, and may undergo longer review. RT isn't suited for static deletions. However, alerts are encouraged for temporary deletions.
Modify Static is the place to truly modify GTFS. Not supported or encouraged.

 

EXPAND ALL COLLAPSE ALL

Shape
 

Static (2–7+ days)

Realtime (~1 minute)
Add Add shape_id to existing trip from trips.txt as desired. Not possible. The shape_id must exist.
Delete Remove shape_id from existing trips from trips.txt as desired. There may be unused shapes. No.
Modify Modify shape as desired. Changes go live in 2 days. No.
Stop
  Static (2–7+ days) Realtime (~1 minute)
Add

Yes. Appropriate stop_times and trip changes might be required. 

Note: New stop names take some time (2+ days) to resolve on Google Maps, subject to review.

No.
Delete Possible. Ensure no stop_times continue to refer to undefined stops.

NO_SERVICE effect on service alert:
Stop will be skipped on every trip it's a part of.

Alternatively, the schedule_relationship of a StopTimeUpdate could be SKIPPED.

Modify Stop revisions may take more than 2 days to resolve due to intensive review process.  No. Only deletion is possible.
Stop time
  Static (2–7+ days) Realtime (~1 minute)
Add Adding a stop_time is equivalent to inserting an existing stop along with a defined trip. Allow 2 days for changes to go live. Not possible.
Delete Remove desired stop_times from desired trips (to remove respective stops from trips). Allow 2 days for changes to go live. The schedule_relationship of a StopTimeUpdate could be SKIPPED.
Modify Modify stop_times file as desired. Changes go live in 2 days.

Fundamentally, vehicle position (VP) and trip update (TU) are modified stop times in RT.

Service alerts with effect
SIGNIFICANT_DELAY and 
MODIFIED_SERVICE can indicate this too.

Service
  Static (2–7+ days) Realtime (~1 minute)
Add The sole purpose of calendar_dates. txt is to allow this change. It takes 2 days to go live, but GTFS need not to be dramatically modified. If service exists in trips, a single-line edit is required. Service and trip at the lowest granularity can be made to have 1:1 mapping.

Use schedule_relationship
values to indicate RT for unplanned trips.

The shape and stop_time must be predefined against an existing trip.

ADDED” copies planned trips with new start_time so long as the parent trip doesn't have block transfers. Consistent start_time is crucial to distinguish between trips.

ADDITIONAL_SERVICE in service alerts is used to describe additional buses deployed on existing service lines. 

Delete

The sole purpose of calendar_dates.txt is to allow this change. It takes 2 days to go live, but GTFS doesn't need to be dramatically modified. 

Delete the service and map linked trips to alternate services.

Alert with effect NO_SERVICE or REDUCED_SERVICE will indicate this to user. Use descriptive text.

A trip update with schedule relationship SKIPPED achieves the same.

Modify Explore calendar.txt and calendar_dates.txt, which can modify operation days for trips through service_id. Not possible. Please note that this is modification. Addition and deletion are possible assuming trips are predefined.
Trip
  Static (2–7+ days) Realtime (~1 minute)
Add The sole purpose of calendar_dates. txt is to allow this change. It takes 2 days to go live, but GTFS need not be dramatically modified. A single line edit is required if service already exists in trips. Service and trip at the lowest granularity can be made to have 1:1 mapping.

Use schedule_relationship
values to indicate RT for unplanned trips.

The shape and stop_time have to be predefined  against an existing trip.

ADDED” copies planned trips with new start_time so long as the parent trip does not have block transfers. Consistent start_time is crucial to distinguish between trips.

ADDITIONAL_SERVICE in service alerts is used to desc
ribe additional buses deployed on existing service lines.

Delete

Remove the trip and ensure all references are removed (frequencies, stop_times, trips). Goes live in 2 days.

Another way to accomplish this is to remove corresponding entries from calendar.txt or add exceptions to calendar_dates.txt.

A trip update with schedule relationship CANCELED achieves this.

Alert with effect NO_SERVICE or REDUCED_SERVICE will also indicate this to user. Use descriptive text.

Modify You can modify trips as needed.

Modification of trip stops isn't permitted, however, delays and early arrivals are indicated through TU or VP.

Stops and parts of trips can be blocked in realtime (see above) through service alerts.

Route
  Static (2–7+ days) Realtime (~1 minute)
Add Addition of a route requires adding a single line to routes.txt. However, this doesn’t have visibility until trips are created and assigned to the said route, under trips.txt. Not possible, nor encouraged.
Delete Remove the route and ensure referencing trips are either removed or assigned to another route. Live in 2 days.

NO_SERVICE would stop all trips associated with this route. Stops on this route would remain unaffected when they're shared with other routes/trips.

Note: Actual route deletion is still a static concept.

Modify You can modify trips as needed. Note: Users identify routes with color/names, frequent change discouraged. Not possible, nor encouraged.

More about realtime feeds

Realtime addition and deletion is possible: To allow this, a sketch of the path, stop_sequence, and stop_time (i.e. a trip to model after) must exist in the static feed.

Creative use of calendar.txt and calendar_dates.txt is encouraged: To capture snow days, specify trips that may not be “in service” but may be taken in the future in case of contingencies (i.e. define trips beforehand). This enables a quick “RT-based disabling/enabling (default)” when the moment arrives.

Note: Realtime modification of shapes or paths and core elements of static feeds aren't currently supported or encouraged.

Frequently Asked Questions

EXPAND ALL COLLAPSE ALL

Q: There’s a small accident at stop X. I want to route around it through stop Y as soon as possible. Can I do this?
A: We can suppress stop X (service alerts). Trips will skip this stop. Adding Y to the schedule isn’t possible, but it’s possible to use above alert to indicate that another intermediate stop may be taken.
Q: It's Y festival here. We have X new lines running and some major modifications. Help!
A: What we can do depends on how soon the festival is.

If the festival is more than 2 days from now:

Use calendar_dates.txt to take all existing modified trips out of service for the duration of the festival. You can also add some new trips for this duration. Adding new stops is difficult, so we hope you planned for this (possible within one week+). Feel free to use existing stops. To modify the stops, complete the following steps:

  1. Create a new calendar and calendar_date entries (new service_id) for affected existing trips containing the regular calendar and the exclusion calendar_dates.
  2. Point affected trips to this new calendar (service_id).
  3. Create calendar_dates entries with a new service_id for the event dates to be used with new special routes and altered versions of affected trips.
  4. Create trips (and shapes) for altered versions of affected trips. Also, create routes, trips, and shapes for special service lines. All of these should point to the service_id created in step 3.
  5. After the event, roll back to previous feed format.

 

If the festival is less than 2 days from now:

We can cancel existing trips, and MODIFIED_SERVICE effect is the right place to communicate this. There isn’t enough time to introduce new stops or stop_times to the routing schedules, however, we can “add vehicles” to existing lines (scheduled or frequency based) to cater to increased service. 

Q: I want to add a new route now!
A: Sorry, we can’t do that. 
Q: I want to add a new trip now!

A: Does the static already have any trip with the same stop_sequences as this trip? If not, it’s not possible to build this into the index in under 2 days. 

However, a trip update (TU) or vehicle position (VP) may be set against a trip with different start times as an ADDED Schedule Relationship trip. This added schedule will use the stops of the trip_id provided but initiate a trip on the new start_time given.

Note: The start_time, direction, start_date and trip_id must remain stable to maintain reference to the trip once added. This isn’t permitted in trips with block transfers. The TU and VP feed may look like the following:

This isn’t a valid RT realtime code, just a guideline.  

# header information
header {
  # version of speed specification. Currently "2.0"
  gtfs_realtime_version: "2.0"
  # determines whether dataset is incremental or full
  incrementality: FULL_DATASET
  # the moment where this dataset was generated on server
  timestamp: 1284457468
}

# multiple entities can be included in the feed
entity {
  # unique identifier for the entity
  id: "add-a-trip"

  # "type" of the entity
  trip_update {
    trip {
      # selects which GTFS entity (trip) will be affected
      Schedule_relationship: ADDED
      trip_id: "tripid_of_trip_to_copy" #defined in Static
      route_id: “routeid_of_trip_to_copy” # defined in Static. 
                                          # Must NOT contain block transfers.
      start_time: “10:00:00” #the local time when this ad hoc trip starts
      start_date: “20180201” #the local date when this ad hoc trip starts
    }
    ...
  }
}

Was this helpful?
How can we improve it?