Describe the Bug
get_language_breakdown (backend/app/services/github_service.py:158) fetches the repo list, then loops up to 20 repos calling /repos/{full_name}/languages one at a time, awaiting each (:168-176) — up to 21 fully sequential round-trips per /github/languages call. The frontend hits this on every dashboard mount and every sync (DashboardPage.tsx:58). Result: multi-second loads and linear rate-limit burn with no caching.
Where
Steps to Reproduce
- Connect a GitHub account with ~20 repos
- Load the dashboard → triggers
/github/languages
- Observe the multi-second response time
Expected Behavior
Fire the per-repo language calls concurrently (single AsyncClient + asyncio.gather, bounded by a semaphore to stay polite to the rate limit), then aggregate — should be sub-second.
Screenshots / Terminal Output
n/a — measurable as endpoint latency scaling with repo count.
Environment
- OS: any
- Browser (if frontend): affects dashboard load
- CLI version (if CLI): n/a
- Commit:
f3dd729
Additional Context
Could also add caching and guard each lang_response.json() for non-200. Happy to take it if you assign me.
Contributing as part of Elite Coders Summer of Code (ECSoC 2026).
Describe the Bug
get_language_breakdown(backend/app/services/github_service.py:158) fetches the repo list, then loops up to 20 repos calling/repos/{full_name}/languagesone at a time, awaiting each (:168-176) — up to 21 fully sequential round-trips per/github/languagescall. The frontend hits this on every dashboard mount and every sync (DashboardPage.tsx:58). Result: multi-second loads and linear rate-limit burn with no caching.Where
clutch-cli)Steps to Reproduce
/github/languagesExpected Behavior
Fire the per-repo language calls concurrently (single
AsyncClient+asyncio.gather, bounded by a semaphore to stay polite to the rate limit), then aggregate — should be sub-second.Screenshots / Terminal Output
n/a — measurable as endpoint latency scaling with repo count.
Environment
f3dd729Additional Context
Could also add caching and guard each
lang_response.json()for non-200. Happy to take it if you assign me.Contributing as part of Elite Coders Summer of Code (ECSoC 2026).