The Problem
Currently, many of our data-heavy API endpoints (especially location-based searches, schedule builders, and hierarchical reference mappers) perform synchronous operations inside large for loops. These operations include heavy math (haversine spatial calculations), sequential database queries, and massive JSON array allocations.
When a client drops their connection early (e.g., closing the mobile app, navigating away, or hitting a timeout), Go automatically cancels the http.Request context. However, because we do not explicitly check this context state deep inside our heavy for loops, the goroutine continues executing these massive calculations for a client that is no longer there.
The Impact
These "ghost requests" needlessly consume CPU and memory. Under high load or during a sudden burst of canceled requests (such as a user panning around a map rapidly), this can lead to severe resource exhaustion, garbage collection pressure, and latency spikes for active users.
Proposed Solution
Implement the "Load Shedding" pattern by adding Deep Context Cancellation checks. We should inject the following check at the top of the heaviest iteration loops and right before massive array filtering operations:
if ctx.Err() != nil {
return // Client disconnected, abandon heavy calculations instantly
}
Affected Areas / Implementation Checklist:
This pattern needs to be applied to the heavy loops in the following files:
Implementing this will make the API dramatically more resilient under load and ensure we instantly free up threads and memory the millisecond a client disconnects.
The Problem
Currently, many of our data-heavy API endpoints (especially location-based searches, schedule builders, and hierarchical reference mappers) perform synchronous operations inside large
forloops. These operations include heavy math (haversine spatial calculations), sequential database queries, and massive JSON array allocations.When a client drops their connection early (e.g., closing the mobile app, navigating away, or hitting a timeout), Go automatically cancels the
http.Requestcontext. However, because we do not explicitly check this context state deep inside our heavyforloops, the goroutine continues executing these massive calculations for a client that is no longer there.The Impact
These "ghost requests" needlessly consume CPU and memory. Under high load or during a sudden burst of canceled requests (such as a user panning around a map rapidly), this can lead to severe resource exhaustion, garbage collection pressure, and latency spikes for active users.
Proposed Solution
Implement the "Load Shedding" pattern by adding Deep Context Cancellation checks. We should inject the following check at the top of the heaviest iteration loops and right before massive array filtering operations:
Affected Areas / Implementation Checklist:
This pattern needs to be applied to the heavy loops in the following files:
internal/gtfs/gtfs_manager.gointernal/restapi/arrivals_and_departure_for_stop.gointernal/restapi/block_handler.gointernal/restapi/reference_utils.gointernal/restapi/route_search_handler.gointernal/restapi/routes_for_location_handler.gointernal/restapi/schedule_for_route_handler.gointernal/restapi/schedule_for_stop_handler.gointernal/restapi/search_stops_handler.gointernal/restapi/shapes_handler.gointernal/restapi/stops_for_agency_handler.gointernal/restapi/stops_for_location_handler.gointernal/restapi/stops_for_route_handler.gointernal/restapi/trip_details_handler.gointernal/restapi/trips_for_location_handler.gointernal/restapi/trips_for_route_handler.gointernal/restapi/vehicles_for_agency_handler.goImplementing this will make the API dramatically more resilient under load and ensure we instantly free up threads and memory the millisecond a client disconnects.