Skip to the documentation

Rate limits

A key has a rate a minute and an optional cap a month. Read the headers, and wait Retry-After on a 429.

A call made with a key is counted against two limits that belong to the key and are shared by every caller using it, whatever their address. They are set when the key is made and can be changed in Settings.

LimitRefillsOn breach
Requests a minuteContinuously, at the pace of the limit. A key can burst a minute's worth.429 rate-limited, Retry-After in seconds.
Requests a month (optional)On the first of the month, UTC.429 monthly-cap-reached, Retry-After until then.
LimitDefaultLeastMost
Requests a minute1201600
Requests a monthNone11,000,000
Lifetime3 months1 week5 years

Headers

Every answer to a call made with a key says where you stand, in the structured syntax of draft-ietf-httpapi-ratelimit-headers-11:

RateLimit-Policy: "key";q=120;w=60
RateLimit: "key";r=87;t=12

q is the quota and w its window in seconds; r is what is left and t the seconds until it is whole again. A key with a monthly cap lists a second item, "month". A limit that refuses stops the check, so a request the minute refused never spends the month.

Handling a 429

  1. Stop sending. Read Retry-After, in whole seconds, and wait at least that long.
  2. Then retry. Add a little jitter if many workers share the key, so they do not all return together.
  3. Poll a run at the Retry-After it gives, not faster; a run changes about once a second at most.
  4. If monthly-cap-reached is a surprise, raise the cap in Settings, or find which job is spending it in the usage report.
async function call(url: string, init: RequestInit, tries = 5): Promise<Response> {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch(url, init)
    if (response.status !== 429 || attempt === tries) return response
    const wait = Number(response.headers.get('Retry-After') ?? 1)
    await new Promise((resolve) => setTimeout(resolve, (wait + Math.random()) * 1000))
  }
}

Other caps

Some work has its own cap, independent of the key, and answers 429 too. These carry no RateLimit headers, which is how to tell them apart from the key's own:

  • Starting runs: 60 an hour per person, and 3 in flight at once (rate-limited, too-many-active).
  • Invitations: 30 a day per org, across Settings and the API (invite-cap-reached).