GitHub API-gränsen för antal anrop har överskridits: vad det innebär och hur det ska hanteras

GitHub begränsar hur många REST API-begäranden som appen kan skicka. När du överskrider en gräns avvisar GitHub dina begäranden med en 403 eller 429 status tills gränsen återställs eller väntetiden har gått ut. GitHub har två typer av gränser: en primär gräns för begäranden per timme och sekundära gränser som skyddar mot plötsliga belastningstoppar. Om din app fortsätter att skicka begäranden medan den är hastighetsbegränsad kan GitHub förbjuda din integrering. Mer information finns i Begränsningar för begärandefrekvens för REST-API:et.

Hur GitHubs frekvensbegränsningar ser ut

Limit Value När du går igenom den
Primär, oautentiserad 60 begäranden per timme, per IP-adress 403 eller 429, och x-ratelimit-remaining är 0
Primär, personlig åtkomsttoken 5 000 begäranden per timme Samma som ovan
Primär i GitHub ActionsGITHUB_TOKEN 1 000 begäranden per timme, per repository Samma som ovan
Secondary Till exempel högst 100 samtidiga begäranden, 900 poäng per minut för REST-slutpunkter och cirka 80 innehållsgenererande begäranden per minut 403 eller 429 med ett felmeddelande. retry-after kan finnas.

GitHub kan ändra sekundära gränser utan föregående meddelande, och det finns inget sätt att kontrollera hur nära du är att nå dem.

Varje svar innehåller header-fält som anger var du ligger i förhållande till den primära gränsen:

Header Vad det säger dig
x-ratelimit-limit Det högsta antalet begäranden du kan skicka per timme
x-ratelimit-remaining Hur många begäranden du har kvar i det aktuella fönstret
x-ratelimit-used Hur många begäranden har du skickat i det aktuella fönstret?
x-ratelimit-reset När fönstret återställs, i UTC-epoksekunder
x-ratelimit-resource Vilken gräns begäran räknas mot

Hantera en GitHub-begränsning av förfrågningshastighet

  1. Skilj en hastighetsbegränsning från ett behörighetsfel. GitHub returnerar 403 också när din token saknar åtkomst. Om svaret inte har någon retry-after, x-ratelimit-remaining är inte 0 och om meddelandet inte nämner någon gräns för begärandefrekvens, är det ett behörighetsproblem. Försök inte med det igen.
  2. Följ retry-after först. Om huvudet finns, vänta det antal sekunder som anges i huvudet.
  3. Annars väntar du på återställningen. Om x-ratelimit-remaining är 0, försök inte igen förrän tiden i x-ratelimit-reset.
  4. Annars, vänta minst 1 minut. För en sekundär gräns utan någon av rubrikerna ber GitHub dig att vänta minst 1 minut och vänta längre efter varje misslyckat nytt försök. Stoppa efter ett angivet antal återförsök och returnera ett fel.
  5. Sakta ned innan du tar slut. Använd x-ratelimit-remaining och x-ratelimit-reset för att fördela dina begäranden. Skapa inte logik kring ett exakt kvarvarande antal, eftersom GitHub kan ändra gränser. Rubrikerna x-ratelimit-* är källan till sanningen, inte GET /rate_limit slutpunkt.
async function githubWaitMs(response, attempt) {
  if (response.status !== 403 && response.status !== 429) {
    return null;
  }
  const retryAfter = response.headers.get('retry-after');
  if (retryAfter) {
    return Number(retryAfter) * 1000;
  }
  if (response.headers.get('x-ratelimit-remaining') === '0') {
    const resetMs = Number(response.headers.get('x-ratelimit-reset')) * 1000;
    return Math.max(resetMs - Date.now(), 0);
  }
  const { message = '' } = await response.clone().json().catch(() => ({}));
  if (response.status === 429 || /rate limit/i.test(message)) {
    return 60_000 * 2 ** attempt;
  }
  // A 403 without rate limit signals is a permission problem: don't retry
  return null;
}

Anroparen försöker igen när funktionen returnerar ett tal och slutar efter några försök.

Så här testar du att din app hanterar GitHub hastighetsbegränsningar

Du når sällan en GitHub API-begränsning när du utvecklar. Du skickar några förfrågningar och 5 000 per timme känns oändliga. Så sättet du testar hantering av anropsbegränsning på avgör om du hittar buggarna innan användarna gör det.

Approach Det här hittar du Vad du saknar
Vänta på produktionsmiljön Faktiska fel Allt, tills en användare trycker på den
Mocka API:et i dina tester eller låt kodningsagenten skriva mocken Om grenen för återförsök körs GitHubs verkliga headers och felsvar, och SDK:ets återförsöksprincip. Din app behöver också en testomkopplare för att nå mocken.
Anropa det verkliga API:et tills du blir begränsad Faktiskt beteende Det tar upp till 5 000 begäranden, du kan inte utlösa en sekundär gräns när som helst och du riskerar ett förbud mot din integration
Fånga upp appens verkliga trafik och returnera svar för hastighetsbegränsning vid behov Verkliga URL:er, din riktiga SDK och återförsöksprincip och GitHub egna rubriker och felformat Ingenting i din app ändras, så den testar inte din kod isolerat. Spara enhetstesterna för det.

Prova det i din app

Dev Proxy fångar upp appens begäranden till api.github.com och returnerar GitHub-liknande svar om hastighetsbegränsning medan appen fortsätter att anropa de verkliga URL:erna. Förinställningen github-rate-limiting räknar dina begäranden mot en gräns på 60 per timme, skickar rubrikerna x-ratelimit-* och returnerar ett 429 med API rate limit exceeded när gränsen är förbrukad. Fram till dess går dina begäranden till GitHub och räknas även mot din verkliga gräns.

Ladda ned förinställningen och starta Dev Proxy med den:

devproxy config get github-rate-limiting
devproxy --config-file "~dataFolder/configs/github-rate-limiting/.devproxy/devproxyrc.json"

Om du vill testa sekundära gränser startar du Dev Proxy med devproxyrc-secondary.json från samma mapp i stället. Den returnerar slumpmässigt en sekundär begränsning av begärandefrekvens 429 med en retry-after header.

Kör sedan appen som vanligt och se vad den gör. Information om hur du installerar Dev Proxy finns i Konfigurera Dev Proxy.

Nästa steg

Se även