Google Transit basics

GTFS modeling: Use static feeds with realtime feeds

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 the reality on the ground.

GTFS modeling basics

  • GTFS Static Feeds: Requires 24–48 hours processing time after submitting to Google, although it can be delayed if Google detects issues in the feed.
    GTFS Static is for premeditated schedule and transit design. You should provide your static feed to Google a minimum of 2 days in advance. However, a week ahead is ideal in case Google detects conflicts or suspicious issues with your feed that require human review.
  • GTFS Realtime Feeds: Updates provided to Google are reflected immediately.
    GTFS Realtime is designed to provide realtime status over static data. It communicates delays through vehicle positions and trip updates for trips or stops predefined in static. It also provides service alerts (delays, service interruptions) to users. 
  • 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 (in realtime) isn't feasible. The addition of services takes 2–7+ days due to a human review process for conflicting or “suspicious” edits.
  • In your static feed, you can use feed_info.txt to pre-determine (2–7+ days in advance) when static changes should go live, making sure to be consistent with your realtime feeds. Use the feed_start_date and feed_end_date fields to specify the dates that your static feed should be active. If the feed_start_date starts in the future (based on when we process it), we’ll still process that feed, but will keep both the current and “future” version. 
  • Static feeds contain core data on routes, stops, and trip scheduling, but as noted above, any changes to static feeds require anywhere from 2–7 days. The following are best practices for how to make scheduling changes.

Best practices to update your static & realtime feeds

Various transit changes occur within ground transportation services, including different durations, levels of urgency, and type of entity. Generally speaking, any changes to core data, including additions, modifications, or deletions of stops, routes, or trips should be performed in the static feed. However, for some changes, particularly temporary changes that need to be made reactively and quickly, there are some methods to achieve this in the realtime feed. Check the following tables for best practices to update the data in your feed.


  Static (2–7+ days) Realtime (~1 minute)
Add data to the feed Most changes are possible and straightforward. In general, this isn't possible unless adding to an existing frequency with schedule_relationship.
Delete data from the feed Significant deletions get flagged as suspicious, and may undergo longer review. The realtime feed isn't suited for static deletions. However, alerts are encouraged for temporary deletions.
Modify data in the feed Most changes are possible and straightforward. Not supported or encouraged.
  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. N/A
Modify Modify shape as desired. Changes go live in 2 days. N/A
  Static (2–7+ days) Realtime (~1 minute)

Yes. Appropriate stop_times and trip changes might be required.

Tip: New stop names take some time (2+ days) to resolve on Google Maps, subject to review.
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 the intensive review process. No. Only deletion is possible.
Stop times
  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 realtime.

Service alerts with effect


MODIFIED_SERVICE can indicate this too.

  Static (2–7+ days) Realtime (~1 minute)

To explicitly activate or disable service by date, use calendar_dates.txt.

Use calendar_dates.txt together with calendar.txt to define exceptions to the default service patterns defined in calendar.txt. If service is generally regular, with a few changes on explicit dates (for instance, to accommodate special event services, or a school schedule), this is a good approach. 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 realtime 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 describe additional buses deployed on existing service lines.


Remove the trip and ensure that 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 SKIPPED achieves this.

Alert with effect NO_SERVICE or REDUCED_SERVICE also indicates this to the user. Use descriptive text.


You can modify trips as needed.

Another way to accomplish this is to have corresponding entries in calendar.txt or add exceptions to calendar_dates.txt.

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 (mentioned above) through service alerts.

  Static (2–7+ days) Realtime (~1 minute)
Add To add a route, add 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 or encouraged.
Delete Remove the route and ensure that referencing trips are either removed or assigned to another route. Goes 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 or trips.

Tip: Actual route deletion is still a static concept.

You can modify trips as needed. 

Tip: Users identify routes with color or names. Frequent change is discouraged.
Not possible or encouraged.


More about realtime feeds

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

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

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

Frequently asked questions

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. It isn’t possible to add Y to the schedule, but it’s possible to use the 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. It is difficult to add new stops, so we hope you planned for this (possible within one week+). You can 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 the 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 will initiate a trip on the new start_time given.

Important: 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 resemble the following:

This isn’t a valid realtime code. It's 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





Need more help?

Try these next steps:

Is there something we can help you with?

Chat with a member of Transit team

Clear search
Close search
Google apps
Main menu