Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

122 linesCodeBlameRaw
1---
2title: Rate limits
3description: How many requests the API, the MCP server, git over HTTPS and the site take a minute, what a limited request is answered with, and how to stay under the limits.
4---
5
6g1t limits how many requests a client can make in a minute, so that one
7client cannot slow g1t down for everyone else or run up a repository
8owner's bill. The limits are well above what a person or an agent working
9normally reaches. Each counts requests over 60 seconds, approximately: a
10client can sometimes get a few more through before it is limited.
11
12## Response headers
13
14REST and MCP responses that pass through an available rate limiter include
15`RateLimit-Policy`. Its Structured Fields syntax follows the IETF HTTPAPI
16[RateLimit draft](https://www.ietf.org/archive/id/draft-ietf-httpapi-ratelimit-headers-10.html),
17which is not yet a published RFC:
18
19```http
20RateLimit-Policy: "anonymous";q=60;w=60
21```
22
23Authenticated requests use `"token";q=1000;w=60`. Quotas are approximate
24per-location limits, not a global accounting balance. Cloudflare's binding
25does not expose a remaining count or reset clock, so successful responses
26do not invent those values. A limited response is HTTP 429 and includes:
27
28```http
29RateLimit-Policy: "anonymous";q=60;w=60
30RateLimit: "anonymous";r=0;t=60
31Retry-After: 60
32```
33
34Wait at least `Retry-After` seconds, then retry with jitter. These headers
35are exposed to browser API clients through CORS. Exempt service callbacks
36and self-hosted installations without a working limiter omit the policy.
37
38## Limits
39
40| Where | Counted by | Requests a minute |
41| --- | --- | --- |
42| REST API, with a token | Token | 1,000 |
43| REST API, without a token | Client IP address | 60 |
44| MCP server | Token | 1,000 |
45| Git over HTTPS, with credentials | Credentials | 1,200 |
46| Git over HTTPS, without credentials | Client IP address | 120 |
47| Anonymous clones of one repository that are not cached | Repository | 120 |
48| Pages on g1t.sh, signed in | Session | 1,200 |
49| Pages on g1t.sh, [with a token](/guides/authentication/#use-a-token-on-the-website) | Token | 1,000 |
50| Pages on g1t.sh, signed out | Client IP address | 600 |
51| [Ask g1t](/guides/ask/) questions | Person | 20 |
52| Archive downloads, workflow run pages, log downloads and search, signed out | Client IP address | 30 |
53| [Raw files](/guides/git/#raw-files) on g1tusercontent.com | Client IP address, together with pages signed out | 600 |
54| [OpenTelemetry ingest](/guides/observability/) at otel.g1t.sh | Client IP address | 600 |
55| Container and package registries | See [storage and pull limits](/guides/containers/#storage-and-pull-limits) | |
56
57The REST API and the MCP server count apart: calls to one do not use up
58the other's limit. A request with a token that is not valid counts against
59its IP address, as a request without a token does. On g1t.sh, every
60request from one IP address, signed in or not, also counts toward 3,000 a
61minute.
62
63Signing up with a password is limited to 5 accounts an hour from one
64network; see [too many attempts](/guides/authentication/#too-many-attempts).
65
66A running job's live log, which its run's page asks for about once a
67second, counts as a page, not as a log download.
68A signed archive link, the address
69`GET /repos/{owner}/{repo}/tarball/{ref}` and `/zipball/{ref}` send you to,
70counts by the link, at the token rate, rather than by address: jobs that
71share an address, as g1t's own machines do, each download their tarball
72without using up each other's limit.
73
74Workflow jobs report to g1t with their own
75credentials. Those reports are not rate limited.
76
77## When you are limited
78
79A request past a limit is answered `429 Too Many Requests` with a
80`Retry-After` header: the number of seconds to wait before trying again.
81
82```http
83HTTP/1.1 429 Too Many Requests
84Retry-After: 60
85Content-Type: application/json
86
87{ "error": { "code": "rate_limited", "message": "Too many requests with this token. Wait a minute and try again: https://docs.g1t.sh/reference/rate-limits/" } }
88```
89
90| Where | Body |
91| --- | --- |
92| REST API and MCP server | JSON in the [error shape](/reference/api/#errors) every endpoint uses, with `code` `rate_limited`. Through MCP it comes back as the HTTP answer to the request, not as a tool result. |
93| Git over HTTPS | Plain text, which git prints after `remote:` or in its error. |
94| Pages on g1t.sh, and raw files | Plain text. |
95
96Branch on the `429` status or the `rate_limited` code, never on the
97message. The API sends `Access-Control-Expose-Headers: retry-after`, so a
98browser app can read the header too.
99
100## Staying under the limits
101
102- **Send a token.** Signed-in limits are much higher than anonymous ones,
103 and they follow the token rather than the network you are on, so people
104 sharing an office or a VPN do not share a limit.
105- **Clone with credentials.** A clone is about three git requests. Use
106 [a token as the password](/guides/git/#authentication) to count against your own
107 limit rather than your network's.
108- **Wait for `Retry-After`.** Retrying sooner is answered `429` again and
109 counts against the limit.
110- **Cache what does not change.** A commit's contents never change: read
111 a commit by its SHA once and keep it.
112- **Use webhooks instead of polling.** A [webhook](/guides/webhooks/)
113 tells you when something changes, without a request a minute.
114
115Repeated anonymous clones of the same commit are answered from a cache and
116do not count against the repository's limit. If a limit gets in the way of
117something you need to do, [contact support](https://g1t.sh/support).
118
119## Running g1t yourself
120
121An installation you run yourself has no rate limits. See
122[run g1t yourself](/guides/self-hosting/).