Il 429 significa che è stato raggiunto un limite. La domanda utile è: il limite di chi — il tuo server web, un proxy o una rete di distribuzione davanti, un'API che stai chiamando, o l'applicazione stessa. Ognuno richiede una soluzione diversa, e le intestazioni della risposta di solito dicono quale.

Leggi prima la risposta

curl -sSI https://yourdomain.com/api/thing | grep -i -E 'retry-after|ratelimit|x-'

Retry-After ti dice quanto aspettare. Le intestazioni RateLimit indicano il tetto e quanto ne resta. Un 429 senza quelle intestazioni viene di solito dal tuo stesso server, o da un proxy che non è stato configurato per spiegarsi.

Se è il tuo Nginx

grep "limiting requests" /var/log/nginx/error.log | tail
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

location /api/ {
    limit_req zone=api burst=20 nodelay;
    limit_req_status 429;
}
Dietro una rete di distribuzione o un bilanciatore, $binary_remote_addr è il PROXY: tutti i visitatori condividono così un unico secchio, e bastano pochi di loro a far scattare il limite per tutti. Configura prima l'indirizzo reale del client — vedi Cloudflare e l'IP vero del visitatore.

Se il limitato sei tu

  • Rispetta Retry-After. Riprovare subito allunga quasi tutti i blocchi.
  • Arretra in modo esponenziale, con una variazione casuale, così una flotta di processi non riprova tutta insieme.
  • Metti in cache ciò che scarichi. Quasi tutti i limiti di frequenza si raggiungono ripetendo la stessa domanda.
  • Raggruppa dove l'API lo consente: una chiamata per cinquanta record invece di cinquanta chiamate.
for i in 1 2 3 4 5; do
  curl -fsS "$URL" && break
  sleep $(( (2 ** i) + RANDOM % 3 ))
done

Se è un punto di accesso

Allora sta funzionando come deve. Vedi Limitare la frequenza su un punto di accesso.