How to Fix Rate Limiting Errors When Using the GitHub Readme Stats Public API

Deploy your own Vercel instance with multiple PAT_* environment variables to eliminate shared API quota constraints, or add stable query parameters to leverage the public service's 5-minute edge cache.

The GitHub Readme Stats public API frequently encounters GitHub's GraphQL rate limits because it runs on a shared Vercel instance with a finite pool of personal access tokens. By understanding the token rotation logic in src/common/retryer.js, you can configure a self-hosted deployment that avoids the "maximum retries exceeded" error entirely.

How the Token Rotation System Works

The service implements a Retryer class in src/common/retryer.js to automatically cycle through available GitHub tokens whenever the API signals a rate limit.

At initialization, the system scans environment variables to count how many PAT_* tokens are defined (lines 9-12), setting this count as the maximum number of retries. When a GraphQL request returns errorType === "RATE_LIMITED" or an error message containing "rate limit" (lines 49-56), the retryer recursively re-attempts the request with the next token in the sequence. If all tokens exhaust their individual 5,000 requests-per-hour quotas, the library throws CustomError.MAX_RETRY and the badge renders a failure state.

Why Rate Limit Errors Occur on the Public API

Shared Token Pool Exhaustion

The public Vercel instance serves thousands of users from a small set of PAT_* tokens. Because GitHub grants only 5,000 GraphQL requests per hour per token, heavy traffic from popular repositories can deplete the entire shared pool, causing the service to return errors for all users until the quota resets.

Multi-Page Repository Fetching

By default, the public instance disables multi-page star counting to conserve API calls. The stats fetcher in src/fetchers/stats.js checks process.env.FETCH_MULTI_PAGE_STARS at lines 47-55; when this value equals "true", the while (hasNextPage) loop (lines 24-55) requests additional GraphQL pages for every repository, multiplying the API cost per profile by 10x or more.

Methods to Fix Rate Limiting Errors

Deploy Your Own Instance with Multiple PATs

Fork the anuraghazra/github-readme-stats repository and deploy it to your personal Vercel account. Generate several GitHub Personal Access Tokens (no special scopes required beyond public_repo) and configure them as environment variables:

PAT_1=ghp_XXXXXXXXXXXXXXXXXXXX
PAT_2=ghp_YYYYYYYYYYYYYYYYYYYY
PAT_3=ghp_ZZZZZZZZZZZZZZZZZZZZ

The retryer automatically detects and uses all PAT_* variables it finds (lines 9-12 in src/common/retryer.js), giving you 5,000 requests per token per hour. With three tokens, you handle 15,000 requests before hitting any limit.

Configure Multi-Page Fetching Settings

Only enable FETCH_MULTI_PAGE_STARS=true if you require accurate star counts across paginated repositories. When disabled (the default), the fetcher stops after the first page, keeping requests well under the rate limit. If you must enable it, ensure you have at least three to five PATs configured to absorb the additional query cost.

Leverage CDN Caching

The public service uses Vercel's edge network to cache rendered SVGs for approximately five minutes. To maximize cache hits and avoid triggering new GitHub API calls, use consistent, stable query parameters in your badge URLs:

![GitHub stats](https://github-readme-stats.vercel.app/api?username=yourname&show_icons=true)

Identical URLs serve cached responses without consuming additional API quota.

Implement Client-Side Fallbacks

Handle the inevitable "down" state gracefully by catching load errors and displaying a static placeholder:

const img = document.getElementById('stats-badge');
img.onerror = () => {
  img.src = '/static/placeholder.svg';
};

This prevents broken images from displaying when the public API exhausts its token pool.

Summary

  • The public API shares a limited pool of GitHub tokens; when all tokens hit the 5,000 request/hour limit, the service returns errors for all users.
  • Self-hosting with multiple PAT_* environment variables is the only guaranteed fix, leveraging the rotation logic in src/common/retryer.js.
  • Disable FETCH_MULTI_PAGE_STARS unless necessary to reduce GraphQL query volume (see src/fetchers/stats.js lines 47-55).
  • Use consistent URL parameters to benefit from Vercel's 5-minute edge caching.
  • Implement onerror handlers to hide broken badges when rate limits occur.

Frequently Asked Questions

What triggers the "maximum retries exceeded" error?

This error occurs when the retryer in src/common/retryer.js exhausts all available PAT_* tokens without successfully fetching data. Each GitHub token allows 5,000 GraphQL requests per hour; when the shared public pool is empty, the library throws CustomError.MAX_RETRY at line 56.

How many GitHub tokens should I configure for self-hosting?

For personal use with low traffic, one token is sufficient. If you enable FETCH_MULTI_PAGE_STARS or serve high-traffic pages, configure three to five tokens. The retryer automatically cycles through any PAT_* variables present in the environment.

Can I fix rate limits without self-hosting?

You can reduce occurrences by using stable query parameters to maximize the 5-minute CDN cache window, but you cannot eliminate the hard limit on the shared public instance. The only permanent solution is deploying your own instance with private tokens.

Does enabling multi-page stars always cause rate limits?

Only if you have insufficient tokens. The while (hasNextPage) loop in src/fetchers/stats.js (lines 24-55) issues one additional GraphQL request per page of repositories. For users with hundreds of starred repos, this quickly exhausts a single token's hourly quota.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →