Skip to content

ListKnownRoutes takes 60s+ for rare IATAs (routes?iata=GPT -> 502) #107

Description

@MrAlders0n

Symptom. GET /api/v1/routes?iata=GPT&limit=50 took 1 minute and returned 500 on analyzer.meshmapper.net (2026-09-02 02:39 UTC); Apache gave up at its 60 s proxy timeout and the browser saw 502 (23 times). Other IATAs answer normally.

Likely cause. ListKnownRoutes (db/queries/queries.sql:1111-1118):

WHERE ($1 = '' OR iata = $1)
  AND ($2 = 0 OR hop_count = $2)
  AND ($3::timestamptz IS NULL OR last_seen < $3)
ORDER BY last_seen DESC
LIMIT $4;

The ($1 = '' OR iata = $1) pattern hides the selectivity of iata from the planner, which then walks idx_known_routes_last_seen backwards looking for 50 matching rows. For a rare IATA that is a scan of nearly the whole table. The existing indexes are (iata), (iata, hop_count) and (last_seen DESC); there is no (iata, last_seen DESC).

Suggested fix.

  • Add CREATE INDEX ... ON known_routes (iata, last_seen DESC).
  • Replace the OR-optional filters with real optional parameters (sqlc.narg) or separate query variants so iata = $1 is visible to the planner when set. EXPLAIN ANALYZE with iata='GPT' before/after to confirm.
  • Independently: the HTTP server has no request timeout (cmd/beacon/main.go http.Server sets none), so a slow query holds a worker for as long as the proxy waits. A ReadHeaderTimeout plus a per-request context.WithTimeout in the handlers (or http.TimeoutHandler) would bound this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingp2-mediumMedium priority

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions