Limiti di frequenza
Come funzionano i limiti separati di lettura e scrittura, quali richieste conteggiano, gli altri limiti e perché la concorrenza è diversa.
Un limite di frequenza stabilisce quante richieste puoi inviare in un breve periodo. Quando lo superi, l'API risponde 429 («troppe richieste») invece di eseguire il lavoro e indica quanto attendere. È una protezione contro script fuori controllo, non una quota sulla quantità di contenuti che puoi generare.
Panoramica dei limiti
| Limite | Valore predefinito | Cosa ricevi quando lo raggiungi | Dettagli |
|---|---|---|---|
| Richieste per account | 1.000 ogni 10 secondi per le letture e altrettante per le scritture | 429 con Retry-After | sotto |
| Richieste di URL di caricamento | 1.000 ogni 10 secondi | 429 con Retry-After | sotto |
| URL di caricamento richiesti ma non ancora usati | 128 file oppure 1 GiB | 429, aspettare non aiuta | sotto |
| Rapporto di utilizzo | 30 al minuto; intervallo di 92 giorni | 429 / 400 | sotto, Fatturazione |
| Saldo disponibile | — | 40201 | Fatturazione |
| Limiti di spesa della chiave (giornaliero / mensile / totale) | Nessuno, a meno che tu lo imposti | 40202 | Fatturazione |
| Limiti giornalieri / mensili del team | Nessuno | 40202 | Fatturazione |
| Team di cui sei proprietario / membri per team | 10 / 100 | 409 nella console | Console e team |
Due contenitori per account: letture e scritture
L'API, cioè tutto sotto /api/v1/* e gli endpoint compatibili /v1/* e /v1beta/*, applica i limiti di frequenza per account, non per chiave: con limiti per chiave chiunque potrebbe aggirarli creando altre chiavi.
Letture e scritture vengono conteggiate in due contenitori separati con la stessa disponibilità. La soglia di protezione predefinita è 1.000 richieste ogni 10 secondi per ciascuno: circa 100 RPS sostenute (richieste al secondo) con un picco di 1.000. È una protezione generale contro abusi e client fuori controllo, non una quota bassa per il normale traffico di generazione a pagamento.
Si tratta di un token bucket, non di un contatore a finestra fissa: capacità di 1.000, reintegrata nell'arco di 10 secondi (circa 100 token al secondo). Ogni richiesta consuma un token; i token tornano costantemente disponibili. A differenza di una finestra fissa, il token bucket rende graduale il reintegro ai confini delle finestre.
Letture e scritture consumano disponibilità separate
Le letture sono tutte le richieste GET — recordInfo, l'elenco jobs, chat/credit, usage, models — più jobs/quote, che calcola soltanto il prezzo di una richiesta. Le scritture sono tutto il resto: createTask, retry, stream, purge, common/upload-url, common/download-url e gli endpoint compatibili chat/completions, messages e di generazione Gemini. Endpoint nativi e compatibili condividono gli stessi due contenitori, quindi spostare un'integrazione di testo da /api/v1 a /v1 non fornisce una seconda disponibilità.
Il polling non può più impedire l'invio delle attività. Un ciclo di polling fuori controllo esaurisce soltanto il contenitore delle letture: recordInfo comincia a restituire 429, mentre createTask continua a essere accettato. Il polling consuma comunque richieste, quindi le integrazioni di produzione dovrebbero ancora preferire i webhook per ridurre chiamate inutili e latenza.
Il catalogo dei modelli usa il contenitore delle letture. Non recuperare uno schema invariato prima di ogni attività; memorizzalo in cache in base alla data di aggiornamento e aggiornalo dopo errori di validazione.
upload-url ha una propria protezione generale di 1.000 richieste ogni 10 secondi, aggiuntiva rispetto al contenitore delle scritture descritto sopra. Protegge separatamente l'autorizzazione alla scrittura nello storage degli oggetti; i caricamenti normali non dovrebbero avvicinarsi a quel limite.
usage ha una protezione aggiuntiva nella direzione opposta: 30 richieste al minuto, molto più restrittive, in aggiunta al contenitore delle letture. Aggrega attività storiche, quindi una chiamata costa molto più di una lettura ordinaria e una sola protezione generale non basta. Usalo per riconciliare i dati, non come endpoint di polling. Inoltre questo contenitore non lascia mai passare richieste in caso di guasto: quando la decisione sul limite non è disponibile restituisce sempre 429, mentre altri contenitori possono essere configurati per consentire il traffico.
URL di caricamento non ancora usati
Separatamente, un account può avere al massimo 128 URL di caricamento non ancora usati, oppure 1 GiB di dimensione dichiarata dei file complessivamente associati a essi. Chiederne un altro restituisce 429 con Too many pending uploads; finish existing uploads before requesting more e senza Retry-After.
Qui aspettare non aiuta, quindi non lasciare che un ciclo generico di tentativi continui inutilmente. Carica e conferma i file già richiesti (oppure lascia scadere gli URL di caricamento, cosa che richiede circa 20 minuti) e lo spazio si libera immediatamente. Di solito significa che uno script richiede URL in blocco senza usarli. Consulta Media.
Tutti i contenitori
I limiti sono applicati per area di API, quindi tutto sotto una stessa area condivide una catena di middleware. Come utente dell'API puoi incontrare i primi cinque:
| Contenitore | Copertura | Conteggiato per | Disponibilità predefinita |
|---|---|---|---|
| (rete) | Ogni richiesta API, prima del controllo della chiave | Indirizzo IP sorgente (IPv6: la sua rete /64) | 6.000 al minuto, molto oltre l'uso normale; molte persone sulla stessa rete aziendale lo condividono |
open_api | Scritture sotto /api/v1/*, /v1/* e /v1beta/* (ogni metodo tranne GET/HEAD, a parte jobs/quote) | account | 1.000 ogni 10 secondi (circa 100 RPS sostenute) |
open_api_read | Letture sotto gli stessi percorsi: GET/HEAD (incluso il catalogo models) e jobs/quote | account | 1.000 ogni 10 secondi (circa 100 RPS sostenute) |
upload_url | /api/v1/common/upload-url | account | 1.000 ogni 10 secondi (in aggiunta a open_api) |
api_usage | /api/v1/usage | account | 30 al minuto (in aggiunta a open_api_read) |
| area della console | Endpoint autenticati /console/v1/* | account | 120 al minuto per le letture e altrettante per le scritture |
catalog | Catalogo pubblico anonimo del sito commerciale (non /api/v1/models) | IP sorgente | 300 al minuto |
Per account, non per chiave
open_api e open_api_read vengono conteggiati per account. Creare altre chiavi non fornisce nulla: se il limite fosse per chiave, aggirarlo richiederebbe un clic nella console.
upload_url e api_usage sono però contenitori effettivamente separati: caricare un'immagine di riferimento consuma un token da open_api e uno da upload_url, leggere una volta usage ne consuma uno da open_api_read e uno da api_usage, e l'esaurimento di uno dei due restituisce 429.
Questi numeri sono valori predefiniti che possiamo cambiare senza un rilascio. La disponibilità attuale è sempre nell'header X-RateLimit-Limit e nella Panoramica della console. Fidati dell'header e non scrivere i valori predefiniti in modo fisso nel client.
Header di risposta
| Header | Presente su | Significato |
|---|---|---|
X-RateLimit-Limit | Ogni risposta | Disponibilità per la finestra corrente |
X-RateLimit-Remaining | Ogni risposta | Token rimanenti |
Retry-After | 429 dovuto a un limite di frequenza | Secondi da attendere, minimo 1 |
Una risposta normale di un account con la disponibilità predefinita contiene:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997X-RateLimit-Remaining viene inviato anche nelle risposte riuscite, così puoi rallentare prima di ricevere un 429 anziché dopo.
Su un 401, questi header descrivono il contenitore per rete (6000), non quello dell'account, perché la chiave non è stata identificata.
Come appare un limite
{
"code": 429,
"msg": "Too many requests. Retry in a moment",
"request_id": "req_…"
}Stato HTTP 429, con Retry-After.
Le richieste oltre il limite vengono rifiutate, non messe in coda
Restituiscono subito una risposta. Metterle in coda accumulerebbe soltanto latenza, lasciandoti una connessione che non risponde mai: più difficile da gestire di un chiaro 429. Una richiesta rifiutata non è mai stata accettata, quindi non costa nulla.
Gestirlo
Leggi Retry-After. Non inviare richieste incessanti a intervalli fissi. Gli esempi si fermano dopo cinque tentativi, evitando anche che il 429 per i «caricamenti in attesa» descritto sopra crei un ciclo infinito.
async function callRespectingLimits(url, init) {
for (let i = 0; i < 5; i++) {
const res = await fetch(url, init);
if (res.status !== 429) return res;
// The server already told you how long to wait; don't guess
const wait = Number(res.headers.get('retry-after') ?? 1);
await new Promise((r) => setTimeout(r, wait * 1000));
}
throw new Error('persistently rate-limited');
}import time, requests
def call_respecting_limits(method: str, url: str, **kwargs) -> requests.Response:
for _ in range(5):
res = requests.request(method, url, **kwargs)
if res.status_code != 429:
return res
# The server already told you how long to wait; don't guess
time.sleep(float(res.headers.get("retry-after", 1)))
raise RuntimeError("persistently rate-limited")La concorrenza è una questione separata
Il limite riguarda la velocità di invio, non quante attività sono in esecuzione
Una volta accettata in coda, un'attività smette di consumare la disponibilità del limite di frequenza. Cento attività che generano contemporaneamente non producono un 429.
Ciò che limita davvero le attività in corso, senza riguardare il limite di frequenza:
- Saldo disponibile: ogni attività in corso blocca fondi. Quando il saldo finisce, le nuove attività ricevono
40201. - Limiti di spesa: giornaliero, mensile e totale della chiave, limiti giornalieri e mensili del team (per chiavi appartenenti a un team) e limite giornaliero della piattaforma. Quando uno di questi raggiunge la soglia, ricevi
40202. Consulta Limiti di spesa. - Capacità di esecuzione: quando un modello non può funzionare affatto, ricevi
50301.
Quindi la risposta a «voglio più attività in esecuzione contemporaneamente» è di solito aggiungere fondi o aumentare un limite di spesa, non aumentare il limite di frequenza.
Chiedere un aumento
La disponibilità attuale è indicata nella Panoramica della console. Per chiedere un aumento, apri una conversazione sotto Assistenza (argomento: Integrazione API) e descrivi il traffico: picco di richieste al secondo, se usi batch e quanto può diventare grande un batch. Questo rende la valutazione molto più rapida.
Nel frattempo, mantieni limitata la concorrenza del client e rispetta Retry-After. Scegli il limite di concorrenza in base al lavoro, al tempo di generazione e al saldo disponibile, anziché abbassarlo artificialmente per adattarlo al limite di frequenza predefinito.
Quando il sistema di limitazione non è disponibile
Il limite di frequenza dipende da un contatore esterno. Se fallisce, la modalità configurata decide cosa succede: consentire (continuare a servire) oppure rifiutare (proteggere la disponibilità). Il rifiuto è la scelta predefinita: «non abbiamo potuto leggere la configurazione» non deve mai diventare «non c'è alcun limite».
Quando è configurato il rifiuto, ricevi 429 con Retry-After: 1, non 500. È intenzionale: 500 significa «abbiamo un guasto» e la grande maggioranza degli SDK client riprova immediatamente, aumentando il carico durante un incidente. 429 con Retry-After significa «rallenta e torna», cioè ciò che serve.
Non leggere quindi 429 come prova che stessi andando troppo veloce. Rispettare Retry-After è la risposta corretta in entrambi i casi.

