doc/administration/settings/user_and_ip_rate_limits.md
{{< details >}}
{{< /details >}}
Rate limiting is a common technique used to improve the security and durability of a web application. For more details, see Rate limits.
The following limits are disabled by default:
[!note] By default, all Git operations are first tried unauthenticated. Because of this, HTTP Git operations may trigger the rate limits configured for unauthenticated requests.
The rate limits for API requests don't affect requests made by the frontend, as these are always counted as web traffic.
You must have administrator access.
To enable the unauthenticated API request rate limit:
In the upper-right corner, select Admin.
Select Settings > Network.
Expand User and IP rate limits.
Select Enable unauthenticated API request rate limit.
3600.3600.To enable the unauthenticated request rate limit:
In the upper-right corner, select Admin.
Select Settings > Network.
Expand User and IP rate limits.
Select Enable unauthenticated web request rate limit.
3600.3600.To enable the authenticated API request rate limit:
In the upper-right corner, select Admin.
Select Settings > Network.
Expand User and IP rate limits.
Select Enable authenticated API request rate limit.
7200.3600.To enable the authenticated request rate limit:
In the upper-right corner, select Admin.
Select Settings > Network.
Expand User and IP rate limits.
Select Enable authenticated web request rate limit.
7200.3600.A request that exceeds a rate limit returns a 429 response code and a
plain-text body, which by default is Retry later.
To use a custom response:
project/:id/jobs per minute{{< history >}}
{{< /history >}}
To reduce timeouts, the project/:id/jobs endpoint has a default rate limit of 600 calls per authenticated user.
To modify the maximum number of requests:
project/:id/jobs per minute value.Response headers include rate limit information for all requests. Use these headers to proactively monitor usage and adjust request patterns to avoid throttling.
Rate limits are enforced through two independent systems:
Rack::Attack middleware rate limits: Applied at the HTTP layer. Examples include authenticated API requests per user, or unauthenticated web requests per IP. These limits are reflected in response headers.A single request can count toward both types of rate limits simultaneously.
Response headers only show the most restrictive Rack::Attack rate limit status.
[!note] Application rate limits are not included in response headers.
A request to create an issue through the API counts toward:
Rack::Attack). Included in response headers.Exceeding the issue creation limit results in a 429 response, even when previous response headers indicated enough remaining authenticated API requests.
The following headers are included in all responses to help clients track their rate limit status:
| Header | Example | Description |
|---|---|---|
RateLimit-Limit | 60 | The request quota for the client each minute. If the rate limit period set in the Admin area is different from 1 minute, the value of this header is adjusted to approximately the nearest 60-minute period. |
RateLimit-Name | throttle_authenticated_api | Name of the throttle applied to the request. |
RateLimit-Observed | 67 | Number of requests associated to the client in the time window. |
RateLimit-Remaining | 33 | Remaining quota in the time window. The result of RateLimit-Limit - RateLimit-Observed. |
RateLimit-Reset | 1609844400 | Unix time-formatted time when the request quota is reset. |
When a client exceeds the rate limit (HTTP status 429), the following additional headers are included:
| Header | Example | Description |
|---|---|---|
RateLimit-ResetTime | Tue, 05 Jan 2021 11:00:00 GMT | RFC2616-formatted date and time when the request quota is reset. |
Retry-After | 30 | Remaining duration in seconds until the quota is reset. This is a standard HTTP header. |
Depending on the needs of your organization, you may want to enable rate limiting but have some requests bypass the rate limiter.
You can do this by marking requests that should bypass the rate limiter with a custom header. You must do this somewhere in a load balancer or reverse proxy in front of GitLab. For example:
Gitlab-Bypass-Rate-Limiting.Gitlab-Bypass-Rate-Limiting: 1 on requests
that should bypass GitLab rate limiting.Gitlab-Bypass-Rate-Limiting.Gitlab-Bypass-Rate-Limiting to a value other than 1 on all requests that
should be affected by rate limiting.GITLAB_THROTTLE_BYPASS_HEADER.
'GITLAB_THROTTLE_BYPASS_HEADER' => 'Gitlab-Bypass-Rate-Limiting' in gitlab_rails['env'].export GITLAB_THROTTLE_BYPASS_HEADER=Gitlab-Bypass-Rate-Limiting
in /etc/default/gitlab.It is important that your load balancer erases or overwrites the bypass header on all incoming traffic. Otherwise, you must trust your users to not set that header and bypass the GitLab rate limiter.
The bypass works only if the header is set to 1.
Requests that bypassed the rate limiter because of the bypass header
are marked with "throttle_safelist":"throttle_bypass_header" in
production_json.log.
To disable the bypass mechanism, make sure the environment variable
GITLAB_THROTTLE_BYPASS_HEADER is unset or empty.
Similarly to the bypass header described previously, it is possible to allow a certain set of users to bypass the rate limiter. This only applies to authenticated requests: with unauthenticated requests, by definition GitLab does not know who the user is.
The allowlist is configured as a comma-separated list of user IDs in
the GITLAB_THROTTLE_USER_ALLOWLIST environment variable. If you want
users 1, 53 and 217 to bypass the authenticated request rate limiter,
the allowlist configuration would be 1,53,217.
'GITLAB_THROTTLE_USER_ALLOWLIST' => '1,53,217' in gitlab_rails['env'].export GITLAB_THROTTLE_USER_ALLOWLIST=1,53,217
in /etc/default/gitlab.Requests that bypassed the rate limiter because of the user allowlist
are marked with "throttle_safelist":"throttle_user_allowlist" in
production_json.log.
At application startup, the allowlist is logged in auth.log.
You can try out throttling settings by setting the GITLAB_THROTTLE_DRY_RUN environment variable to
a comma-separated list of throttle names.
The possible names are:
throttle_unauthenticated
throttle_unauthenticated_api or throttle_unauthenticated_web instead.
throttle_unauthenticated is still supported and selects both of them.throttle_unauthenticated_apithrottle_unauthenticated_webthrottle_authenticated_apithrottle_authenticated_webthrottle_unauthenticated_protected_pathsthrottle_authenticated_protected_paths_apithrottle_authenticated_protected_paths_webthrottle_unauthenticated_packages_apithrottle_authenticated_packages_apithrottle_authenticated_git_lfsthrottle_unauthenticated_files_apithrottle_authenticated_files_apithrottle_unauthenticated_deprecated_apithrottle_authenticated_deprecated_apithrottle_unauthenticated_git_httpthrottle_authenticated_git_httpFor example, to try out throttles for all authenticated requests to
non-protected paths can be done by setting
GITLAB_THROTTLE_DRY_RUN='throttle_authenticated_web,throttle_authenticated_api'.
To enable dry run mode for all throttles, the variable can be set to *.
Setting a throttle to dry run mode logs a message to the
auth.log when it would hit the limit, while letting the
request continue. The log message contains an env field set to track. The matched
field contains the name of throttle that was hit.
It is important to set the environment variable before enabling the rate limiting in the settings. The settings in the Admin area take effect immediately, while setting the environment variable requires a restart of all the Puma processes.
If many users connect to GitLab through the same proxy or network gateway, it is possible that, if a rate limit is too low, that limit will also lock administrators out, because GitLab sees them using the same IP as the requests that triggered the throttling.
Administrators can use the Rails console to disable the same limits as listed for
the GITLAB_THROTTLE_DRY_RUN variable.
For example:
Gitlab::CurrentSettings.update!(throttle_authenticated_web_enabled: false)
In this example, the throttle_authenticated_web parameter has the _enabled name suffix.
To set numeric values for the limits, replace the _enabled name suffix with the _period_in_seconds and _requests_per_period suffixes.