-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Description
The trips-for-location endpoint currently exhibits a severe N+1 query pattern. For every vehicle visible in the requested bounding box, the server executes multiple synchronous database queries inside a loop.
This results in linear O(N) performance degradation. In high-density transit areas (e.g., a downtown view with 50+ vehicles), a single API request triggers hundreds of database queries, causing significant latency and database contention.
Technical Detail
- File:
internal/restapi/trips_for_location_handler.go - Function:
buildTripsForLocationEntries
The function iterates over the activeTrips map. Inside this loop, it calls buildScheduleForTrip, which triggers the following database queries for each vehicle:
GetShapePointsByTripID(Fetch shape geometry)GetTrip(Fetch trip details)GetNextAndPreviousTripIDs(Fetch block information)GetStopsByIDs(Fetch stop coordinates for distance calculation)
Impact
- Scalability: The endpoint effectively DDOS-es the database as the number of vehicles increases.
- Latency: API response times degrade linearly.
- 1 Vehicle ≈ 5 DB queries
- 50 Vehicles ≈ 250+ DB queries (Single Request)
Steps to Reproduce
- Start Maglev with a GTFS feed containing active real-time vehicles.
- Make a request to
/api/where/trips-for-location.jsonwith a bounding box large enough to capture 20+ vehicles. - Set
includeSchedule=true. - Observe the database logs or request latency; the query count will match
N * 4(approx).
Proposed Solution
Refactor the handler to use a Bulk Retrieval pattern:
- Phase 1 (Collection): Iterate over visible vehicles to collect all
TripIDs andBlockIDs into slices. - Phase 2 (Bulk Fetch): Execute single batch queries to fetch all Trips, Shapes, StopTimes, and Block-Trips at once.
- Phase 3 (Assembly): Convert the bulk data into in-memory maps and assemble the response without further DB calls.
I have a working implementation of this fix that reduces the query count to a constant ~5 queries regardless of vehicle count.