429 Too Many Requests oznacza, że serwer ogranicza Twoje żądania: klient wysłał w danym okresie więcej żądań, niż serwer dopuszcza, i powinien odczekać, zanim spróbuje ponownie. Nic nie jest zepsute, a natychmiastowe powtórzenie żądania tylko pogarsza sprawę. Dobrze działający serwer podaje w nagłówku Retry-After, ile trzeba czekać; dobrze działający klient czeka co najmniej tyle, a bez tego nagłówka wydłuża kolejne przerwy (backoff). Gdy monitor trafia na 429, zwykle wystarczy wyłączyć go spod limitu albo sprawdzać endpoint bez limitu.
Jak działają limity żądań
RFC 6585 definiuje kod 429, ale same zasady pozostawia każdemu serwerowi. Limit składa się z trzech elementów:
Kogo się liczy: adres IP, klucz API, konto użytkownika albo ich kombinację. Limity na adres IP liczą razem wszystkich, którzy korzystają z tego samego adresu.
Co się liczy: wszystkie żądania albo tylko niektóre, np. logowania, wyszukiwania lub kosztowny endpoint API – często z ostrzejszym limitem.
Jak liczy się czas: stałe okno zeruje się co pełną minutę; okno przesuwne bierze pod uwagę ostatnie 60 sekund; token bucket uzupełnia się w stałym tempie i dopuszcza krótkie serie żądań do swojej pojemności.
Odpowiedź często mówi, na czym stoisz:
HTTP/2 429
retry-after: 30
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
x-ratelimit-reset: 1793091600
Retry-After jest standardowy i zawiera liczbę sekund albo datę HTTP. Nagłówki X-RateLimit-* to raczej powszechna konwencja niż standard, a ich znaczenie bywa różne: reset może być czasem uniksowym albo liczbą sekund, więc sprawdź dokumentację API. Szkic IETF definiuje standardowe pola RateLimit i RateLimit-Policy, które niektóre API już zaczęły wysyłać.
Skąd biorą się błędy 429
Zewnętrzne API, z których korzystasz, np. usługi płatności, poczty, map lub czatu, które ograniczają każdy klucz lub konto.
Twoja własna bramka API lub framework, za pomocą middleware ograniczającego żądania.
Twój serwer WWW. limit_req w nginx domyślnie zwraca 503; ustaw limit_req_status 429, żeby klienci wiedzieli, że mają zwolnić, a nie zakładali awarii.
CDN-y i WAF-y, za pomocą reguł limitowania żądań. W zależności od reguły odpowiedzią jest 429, 403 albo strona z wyzwaniem.
Ochrona logowania i formularzy w CMS-ie lub wtyczce bezpieczeństwa, która ogranicza liczbę prób z jednego adresu.
Obsługa 429 po stronie klienta
Respektuj Retry-After. Czekaj co najmniej tyle, ile podaje. Wcześniejsza próba zwykle kończy się kolejnym 429 i może przedłużyć blokadę.
Stosuj wykładniczy backoff z jitterem. Bez Retry-After czekaj dłużej po każdym niepowodzeniu, np. 1, 2, 4 i 8 sekund, plus losowy dodatek, żeby wielu klientów nie ponawiało żądań w tej samej chwili.
Ogranicz liczbę ponowień. Po kilku próbach zrezygnuj i zgłoś błąd albo odłóż zadanie do kolejki na później.
Wysyłaj mniej żądań. Cache’uj odpowiedzi, korzystaj z endpointów wsadowych, pobieraj większe strony wyników i używaj webhooków zamiast odpytywania, jeśli API je oferuje.
Rozłóż zaplanowane zadania w czasie. Cron joby, które startują o pełnej godzinie, razem trafiają na limity; przesuń je o kilka minut. Przewodnik po wyrażeniach cron pokazuje, jak to zrobić.
async function fetchWithBackoff(url, options = {}, attempts = 5) {
for (let attempt = 0; attempt < attempts; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
const retryAfter = Number(response.headers.get(’retry-after’));
const wait = retryAfter > 0 ? retryAfter * 1000 : 2 ** attempt * 1000 + Math.random() * 1000;
await new Promise((resolve) => setTimeout(resolve, wait));
}
throw new Error(’Still rate limited after ’ + attempts + ’ attempts’);
}
Ten szkic odczytuje Retry-After tylko jako liczbę sekund; kod produkcyjny powinien obsługiwać też format daty.
Ustawianie limitów żądań we własnym serwisie
Zwracaj 429, a nie 503 czy 403. 503 wygląda jak awaria, a 403 jak trwała odmowa; 429 mówi klientom i narzędziom monitorującym dokładnie, co się stało.
Wysyłaj Retry-After, żeby klienci nie musieli zgadywać.
Tam, gdzie się da, limituj po kluczu lub koncie. Limity na adres IP karzą biura, szkoły i sieci komórkowe, w których wiele osób korzysta z jednego adresu.
Dopuszczaj serie żądań. Wczytanie strony może wywołać dziesiątki żądań naraz; token bucket z zapasem na serię nie blokuje zwykłych odwiedzających.
Wyłącz monitoring spod limitu albo daj mu osobny endpoint health check bez limitu.
# nginx: 10 requests a second per address, bursts of 20, answered with 429
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
}
}
Dlaczego monitor dostępności może trafić na 429
Jedno sprawdzenie na minutę brzmi niewinnie, ale żądania sumują się w sposób, który łatwo przeoczyć:
Kilka monitorów na jednym hoście. Dziesięć monitorów tego samego API, z których każdy sprawdza co minutę, to dziesięć żądań na minutę od tego samego klienta – plus ponowne sprawdzenia potwierdzające, gdy coś przestaje działać.
Ostre limity na sprawdzanej ścieżce. Strony logowania, wyszukiwarki i endpointy formularzy często dopuszczają tylko kilka żądań na minutę z jednego adresu.
Współdzielone adresy. Sprawdzenia usługi monitorującej pochodzą z kilku znanych adresów. Limit na adres IP liczy razem wszystkie sprawdzenia z danego adresu, także sprawdzenia tego samego publicznego serwisu lub API wykonywane przez innych użytkowników.
Reguła dla botów, która limituje żądania. Niektóre firewalle liczą klientów automatycznych osobno i ograniczają ich mocniej niż przeglądarki.
Co zrobić, po kolei: wyłącz monitor spod limitu po jego adresach IP, monitoruj endpoint health check bez limitu, sprawdzaj rzadziej albo połącz monitory, które odpytują to samo API. Nie uznawaj 429 za dostępne we wszystkich przypadkach, bo o limicie, który zaczyna blokować Twoich prawdziwych użytkowników, warto wiedzieć. Artykuł Kody statusu HTTP w monitoringu wyjaśnia, które kody traktować jako błędy, a checklista monitorowania API – co jeszcze obserwować w API.
Błędy 429 a Uptimecheck
W monitorowaniu dostępności i monitorowaniu API w Uptimecheck kod 429 wykracza poza domyślnie oczekiwane statusy (od 200 do 399), więc liczy się jako awaria, gdy potwierdzi ją drugie sprawdzenie. Gdy serwer zwraca zwykłe 429, incydent informuje, że nasze sprawdzenia są limitowane, podaje wartość Retry-After, jeśli serwer ją przesłał, i sugeruje wyłączenie spod limitu żądań, których user agent zawiera „Uptimecheck”, rzadsze sprawdzanie albo użycie endpointu bez limitu. Sprawdzenia odbywają się ze Sztokholmu w Szwecji; artykuł Jak przepuścić Uptimecheck przez firewall podaje adresy do wyłączenia spod limitów wraz z regułami dla Cloudflare (także dla jego reguł limitowania żądań) i dla nginx. Interwał każdego monitora wybierasz sam – od co minutę do co godzinę.
Uptimecheck stosuje te same zasady przy wysyłaniu Twoich alertów. Jeśli Slack, Microsoft Teams, Discord lub PagerDuty odpowie kodem 429, alert jest ponawiany po 30 sekundach, 2 minutach, 10 minutach i 30 minutach – i nigdy wcześniej, niż prosi Retry-After usługi, maksymalnie do godziny. Zobacz, dlaczego alerty mogą nie docierać, aby dowiedzieć się, co się dzieje, gdy kanał wciąż zawodzi.
Odróżniaj limit żądań od awarii. Wypróbuj Uptimecheck bezpłatnie przez 14 dni, bez karty kredytowej.