Skip to main content
← Back to list
01Issue
BugShippedSwamp Club
Assigneeskeeb

Relationships

#926 Request-path external fetches with no timeout / no negative cache: profile GitHub/Discord resolution and landing-page total count (30s → 504 mechanism)

Opened by keeb · 7/2/2026· Shipped 7/3/2026

From the 2026-07-02 full-stack performance audit. Two request-path external fetches with no timeout — the cleanest 30s/504 mechanisms found outside /lab (the app's own middleware timeout is 30s, so a hung upstream connection rides all the way to a 504).

1. Profile pages call GitHub/Discord APIs synchronously, unauthenticated, with no timeout and no negative caching

lib/app/resolve-linked-accounts.ts:34-53, 73-100, called from routes/u/[username].tsx:176. For each linked account without a cached providerUsername, the profile GET fetches https://api.github.com/user/{id} (unauthenticated — 60 req/hr/IP) or Discord, serially in a for loop, then writes the cache back.

Two traps:

  • Failures are not cached (if (resolved) at :44): once GitHub rate-limits our egress IP, resolution fails, nothing is cached, and every subsequent view of that profile re-fires the external call forever — a permanent per-view external round trip.
  • No AbortSignal/timeout on either fetch (verified by grep): a hung provider connection holds the request until the 30s middleware cap → 504.

Fix: AbortSignal.timeout(2000) on both fetches; cache negative results with a TTL; authenticate the GitHub call (5k/hr); ideally move resolution to a background/queue refresh and render whatever is cached.

2. Landing page total-count fetch has no timeout

routes/index.tsx:14-24: fetchTotalCount hits the telemetry service with no abort — unlike http-telemetry-stats-repository.ts:16, which correctly uses a 3s AbortSignal. A telemetry stall hangs the homepage to the 30s cap.

Fix: AbortSignal.timeout(1500) + a short in-process cache (the count changes slowly).

House rule worth adopting from this: any fetch on a request path carries an AbortSignal, and null results from external resolution are cached with a TTL like any other result.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 4 MOREPR_MERGED+ 1 MORENOTIFICATION_SKIPPED

Shipped

7/3/2026, 12:40:56 AM

Click a lifecycle step above to view its details.

03Sludge Pulse
keeb assigned keeb7/2/2026, 9:30:35 PM

Sign in to post a ripple.