Skip to content

perf: share data fetch across endpoints to avoid rate limits#4

Merged
costajohnt merged 1 commit into
mainfrom
perf/share-fetch-across-endpoints
May 6, 2026
Merged

perf: share data fetch across endpoints to avoid rate limits#4
costajohnt merged 1 commit into
mainfrom
perf/share-fetch-across-endpoints

Conversation

@costajohnt
Copy link
Copy Markdown
Owner

Summary

The pagination fix in #1 raised per-fetch cost from 3 to up to 12 search calls. With 4 widget endpoints (card, recent, top-repos, activity) each fetching independently on cold-start, a burst can issue ~48 search calls and trip GitHub's 30/min limit. This was observed in production minutes after the fix shipped — every endpoint returned `GitHub API rate limit reached` SVGs until the bucket reset.

This change adds a module-level promise cache keyed by username (`lib/contribution-cache.ts`). Concurrent endpoint hits share one in-flight fetch. Each cold-start instance makes one `fetchContributionData` call per username regardless of how many endpoints get hit.

  • Errors and rejected promises are not cached — next call retries
  • `?cache=no` propagates as a `force: true` flag, bypassing both the SVG cache and the new data cache
  • 1hr TTL matches the existing per-endpoint SVG cache

Test plan

  • `pnpm test` — 114/114 (4 new cache tests + 1 cache-reset hook in endpoint-handler tests)
  • `pnpm run typecheck` — clean
  • After deploy, verify card + top-repos serve fresh data simultaneously without rate-limit errors
  • Verify `?cache=no` still forces a fresh fetch end-to-end

…te limits

The pagination fix (24d6cd5) raised the per-fetch cost from 3 to up to 12
search API calls. With 4 widget endpoints fetching independently on cold
start, a burst can hit ~48 search calls and trip GitHub's 30/min limit.
Observed in production immediately after the fix shipped.

This adds a module-level promise cache keyed by username so concurrent
endpoint hits share a single in-flight fetch. Each cold-start instance now
makes one fetchContributionData call per username regardless of how many
endpoints are hit. The ?cache=no query param still forces a fresh fetch.

Errors and rejections are not cached — next call retries.
@costajohnt costajohnt merged commit bb5849f into main May 6, 2026
4 checks passed
@costajohnt costajohnt deleted the perf/share-fetch-across-endpoints branch May 6, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant