Explainer · Feeds & Standards
What GTFS-Realtime is, and how a feed works
GTFS-Realtime is the standard for live transit data: what a feed carries, how Protocol Buffers structure it, and why the quality rests on the systems behind it.
GTFS-Realtime, often shortened to GTFS-RT, is the standard that carries live transit information: when the next bus is actually coming, where the vehicle is right now, and what is disrupted on the network. It is a feed specification that public agencies publish and that apps read, and it is the moving-picture companion to the static GTFS schedule. The schedule says what is supposed to happen. GTFS-Realtime says what is happening.
The name causes some confusion, so it helps to be precise. GTFS-Realtime is a publishing format, not a tracking system: it does not locate vehicles or compute arrivals on its own. It is the agreed shape of the message an agency puts on the web once its own systems have already worked out the location and the prediction. That distinction matters, because it explains why two agencies can both publish valid GTFS-Realtime and still deliver very different experiences. The format is the easy part.
What a feed carries
A GTFS-Realtime feed is built from three kinds of entity, and every agency that runs a live feed publishes one or more of them. They line up with the questions a rider actually asks.
| Entity type | What it carries | The question it answers |
|---|---|---|
| TripUpdate | Predicted arrival and departure times at each stop, carried as StopTimeUpdates, plus delays, skipped stops, and cancellations | When will my bus actually get here? |
| VehiclePosition | The vehicle’s live location, bearing, speed, which stop it is working toward, and optional occupancy | Where is the vehicle now? |
| Alert | Human-readable messages about disruption, the stops or routes affected, the cause, the effect, and when it applies | What is disrupted, and why? |
Trip updates are the workhorse. The specification describes them as fluctuations in the timetable, and each one is a set of per-stop predictions expressed either as an absolute time or as a delay in seconds against the schedule. That framing is deliberate. A trip update is anchored to a scheduled trip in the static GTFS, so a prediction is always “this scheduled trip, running this many seconds late” rather than a free-floating estimate. The countdown clock on a bus-stop sign and the arrival time in a trip planner are both reading trip updates.
Vehicle positions are the raw geography. The spec is blunt about where the data comes from: a vehicle position provides automatically generated information on the location of a vehicle, such as from a GPS device on board. Latitude and longitude are reported in the standard WGS-84 coordinate system, alongside bearing, speed, and a status flag for whether the vehicle is in transit to, incoming at, or stopped at its next stop. Occupancy and congestion fields exist too, though agencies populate those far less consistently than location.
Service alerts are the words. When a station closes or a route detours, the alert entity carries the human-readable text, points at the affected agency, route, trip, or stop, and records a cause and an effect from a fixed list. The spec draws a clean line here that producers sometimes miss: delays and cancellations of individual trips belong in trip updates, and alerts are for the broader disruption a rider needs to read in sentences.
How the feed is built
Underneath, a GTFS-Realtime feed is a single Protocol Buffers message. Protocol Buffers, or protobuf, is Google’s language-neutral, platform-neutral format for serializing structured data. You define the shape once in a schema file, and a compiler generates the code to read and write it in whatever language you use. The result is a compact binary payload rather than text, which the protobuf documentation sums up as being like JSON, only smaller and faster. That choice is the reason an entire fleet can be re-fetched frequently without moving much data.
The shape of that message is fixed by one schema file,
gtfs-realtime.proto, and the whole standard nests inside three messages. A FeedMessage
wraps one FeedHeader and a repeated list of FeedEntity. Each FeedEntity, in turn, carries
exactly one of the entity types from the table above. Learn those three names and you have
read the structure of every GTFS-Realtime feed there is.

The FeedHeader is small but load-bearing. It carries a gtfs_realtime_version string, which
is currently 2.0, and a timestamp marking the moment the content was built, so a consumer
can tell how fresh the data is. It also carries an incrementality field, and this is where a
practical constraint hides. The specification defines two modes, FULL_DATASET and
DIFFERENTIAL, and per the GTFS-Realtime reference,
DIFFERENTIAL is currently unsupported. In practice that means every feed runs as a full
dataset: each fetch returns the complete current state of every trip, vehicle, and alert, not
a delta since last time. There is no standard way to subscribe to just the changes.
How one prediction reaches a rider
Because the feed is a full snapshot, the model on the consumer side is a poll, not a subscription. A feed is a stream of these messages, and each message is obtained as the response to an ordinary HTTP GET request against a feed URL. An app fetches the current feed, decodes the protobuf, uses what it needs, and comes back on a short interval for the next snapshot. Nothing is pushed.
That is only the final step of a longer chain. Following it backward is the quickest way to see why a technically clean feed can still show a rider the wrong time.

The location starts on the vehicle, usually from onboard GPS, and flows into the agency’s automatic vehicle location system, the same fleet-management platform dispatchers watch. A feed producer then does the real work: it matches each vehicle to a scheduled trip, computes how late that trip is running, projects that delay forward to the stops still ahead, and encodes the whole picture as a protobuf message. That message goes up at an HTTP endpoint, and the rider’s app pulls it down. The standard governs only the last stretch, from the producer’s output to the app’s input. Everything upstream, the accuracy of the GPS and the quality of the prediction model, is the agency’s own system and is where feeds mostly differ.
Why it matters for the data layer
GTFS-Realtime is one of the standards that makes the transit part of intelligent transportation systems actually interoperable. It first appeared in 2011, added to the static GTFS that a few years earlier had already turned agency schedules into a format any app could read. GTFS-RT did the same thing for live data. Before it, every agency that wanted real-time arrivals in a third-party app had to strike a custom integration, and most simply did not. A single published format is what let one app show live buses across many cities without negotiating a separate interface for each agency.
The catch is the one the flow diagram makes plain. A valid feed is a low bar. The protobuf will parse, the three entities will be well formed, and the arrivals can still be wrong, because the predictions were built on stale positions or a mismatch against the schedule. This is the recurring lesson of the data layer: the standard guarantees that systems can exchange data, not that the data is any good. Conformance and feed quality are separate problems from format, and they are where the harder work sits.
What to watch
The core three entities have been stable for years, but the specification is still moving at the edges. Newer entity types, including shapes, stops, and trip modifications, have been added to the schema to describe detours and reroutes more precisely than an alert can, and some fields carry an experimental label until adoption settles. Occupancy data is the clearest example of a field that exists in the spec but that riders cannot yet count on, because it depends on onboard passenger counters that many fleets do not have. When you evaluate a feed, read the version in the header, then check which optional fields the producer actually populates rather than assuming the spec’s full menu is on the table.
The thing to hold onto is the division of labor. GTFS-Realtime gives the industry a shared answer to a narrow question: how should live transit data be shaped so that anyone can read it. That question is settled, and settling it was worth a great deal. The open questions, the ones that decide whether the countdown clock is right, live one step upstream, in the systems that produce the feed rather than the format that carries it.
Common questions
- What is GTFS-Realtime?
- GTFS-Realtime, often shortened to GTFS-RT, is the standard that carries live transit information: when the next bus is actually coming, where each vehicle is, and what is disrupted on the network. It is a feed specification agencies publish and apps read, the moving-picture companion to the static GTFS schedule.
- Is GTFS-Realtime a vehicle tracking system?
- No. It is a publishing format, not a tracking system: it does not locate vehicles or compute arrivals on its own. It is the agreed shape of the message an agency puts on the web once its own systems have already worked out the location and the prediction.
- What does a GTFS-Realtime feed carry?
- Three kinds of update: trip updates (delays and predicted times), vehicle positions (where vehicles are right now), and service alerts (disruptions on the network). Every agency running a live feed publishes them in the same message shape.