Configuring GitLab rate limits

Rate limits slow abusive or runaway traffic on a self-managed GitLab instance. This page explains which settings the hardening guide asks you to enable, why the defaults fit most instances, and how to exempt service users from Notes and Users API limits.

On this page

Why GitLab rate limits matter for a self-managed instance

Rate limits cap how many requests a single user, IP address or endpoint can make to a self-managed GitLab instance within a set period. When a client exceeds the threshold, GitLab rejects further requests until the window resets, so one misbehaving script cannot starve everyone else. The GitLab hardening recommendations ask administrators to enable every rate limit available in the application settings. That instruction is simple to follow on paper, but each limit changes how traffic is handled, so understand what it protects before you switch it on. GitLab describes its hardening guidance as a work in progress that should be rolled out gradually, so treat the list as a working direction and check it against each release.

Teams usually need rate limits for one of three reasons. The first is public exposure: if self-registration is open, projects are public, or the instance is reachable from the internet, anonymous and automated clients can send volumes of requests that an internal user never would. The second is shared CI load, where many pipelines, runners and jobs call the API at the same time, often during a release window. The third is scripted API use, such as inventory tools, mirroring jobs or chat integrations that poll endpoints in tight loops. Before you enable anything, confirm which of these applies to your instance by reviewing your access logs and identifying the top API clients and the endpoints they call most often.

Plan the change as a staged rollout. Enable limits on a non-production instance or during a quiet period first, watch for legitimate clients that start receiving rejections, and record each setting you change so the decisions can be reviewed later. Confirm every limit name and default against the documentation for your installed version, because the hardening guidance evolves and the settings are version-specific. The sections that follow explain how the default values suit most instances and how service users can be exempted from the Notes and Users API limits.

Which rate limit settings cover which traffic

Web limits govern browser traffic to the GitLab interface, including sign-in attempts, password reset requests and page loads. They are the first line of defense against credential stuffing and automated scraping of the web interface. Most developers never reach these thresholds, but many users behind one office gateway or a proxy that hides client addresses can share a single counted address.

  • Sign-in attempts: Limits repeated failed logins per address and per account, which slows password guessing. Confirm the exact setting names in the hardening guide.
  • Password reset requests: Stops attackers from flooding users with reset emails or probing which accounts exist.
  • Unauthenticated page traffic: Slows broad crawling of public pages on instances where anonymous visibility is allowed.
  • Who is affected: Everyone behind a shared public address, including offices that use one egress IP and load balancers that do not forward the original client address.

Check that your reverse proxy passes the real client address, because a misconfigured proxy makes every user look like one client and can trip limits for the whole organization.

Rate limit options and when each fits

This table compares four ways to handle GitLab rate limits: keeping defaults, enabling every limit from the hardening guide, raising ceilings for named service users, and exempting service accounts from Notes and Users API limits. Read each row for the risk it addresses and the cost to CI jobs and integrations. The main takeaway is that the right choice depends on which identities generate traffic, so measure that before changing anything.

OptionRisk it addressesTypical fitTrade-off for CI jobs and integrations
Keep the default limitsAccidental overload at ordinary load, with less protection against scripted abuseSmaller internal instances with no public exposure and little automated trafficPipelines keep current behavior, but bursts from new jobs may go unnoticed until failures appear
Enable every limit in the hardening guideCredential stuffing, scraping, user enumeration and bulk API abuseInternet-facing or regulated instances where the hardening guide is the agreed baselinePipelines, mirroring and bots may hit limits and fail; confirm their traffic in logs first
Raise limits for named service usersLegitimate automation being throttled without weakening limits for everyone elseKnown integrations with predictable, high-volume API callsHigher ceilings apply to that account, so a leaked token gets more room; scope and rotate it
Exempt service accounts from Notes and Users API limitsBots writing many notes or reading user lists being blocked during normal workCI status bots, comment writers and directory sync jobs running on fixed schedulesRemoves a control for that identity; a compromised token can bypass those limits, so monitor it closely
Review logs before changing any limitTuning limits blind, which breaks pipelines or leaves gapsEvery instance, before and after any changeNeeds administrator time and log access; confirm the exact limits and identities with your version's documentation

Enabling and verifying rate limits step by step

This sequence moves a self-managed GitLab instance from its current throttling state to a documented, tested set of rate limits, with exemptions limited to the service users that need them. Each step ends with a check so the team can show what changed and how the limits behave under load.

  1. Review current application settings and integrations

    Start by recording what the instance currently enforces. An administrator opens the Admin Area and reviews the rate limit and related network settings, then lists every integration, bot, CI job and script that calls the API or the Notes endpoints. Include chat integrations, issue sync tools, mirroring jobs, monitoring probes and any scheduled automation. Ask the owners of each caller which account it uses, how often it runs and whether it sends bursts of requests. The step is done when you have a written inventory with the current setting values, the caller list and a named owner for each caller. Confirm the exact setting names against the hardening documentation for your installed version, because the names and location can differ between releases.

  2. Record baseline API and CI traffic

    Before changing any limit, measure normal behavior. Use the logs and metrics your monitoring setup already collects, such as web and API request logs and the Prometheus metrics your GitLab deployment exposes, to capture request rates for the API, the Notes endpoints and pipeline activity over a representative period that includes peak working hours and scheduled jobs. Note which service accounts generate most of the traffic. The output is a baseline table or dashboard that shows typical and peak rates per endpoint group and per account. Without this baseline, you cannot tell whether a later throttled response is a genuine abuse signal or a legitimate job that needs an exemption. Keep the baseline with the change record so auditors can see why each value was chosen.

  3. Set the values for each rate limit

    Apply the limits the hardening guidance describes in a non-production instance first. Decide, for each setting, whether you keep the default or set a value that reflects the baseline you recorded, and document the reason for every change. Most instances can keep the defaults, so only deviate where the baseline or your risk assessment supports it. Enable the settings in the Admin Area or in gitlab.rb according to how your instance is managed, then apply the configuration using your normal reconfigure procedure. The check is that the Admin Area shows the intended values and that the configuration file matches them, so the two sources of truth do not drift. Record the change request reference and the person who approved the values.

  4. Identify service users that need exemptions

    Using the caller inventory and baseline, decide which service accounts need exemptions from the Notes and Users API limits. Only grant an exemption to an account that has a documented need, such as a integration that legitimately reads many notes or a sync job that lists many users. Prefer narrow, dedicated service accounts over human accounts or shared credentials, and confirm that each account has the minimum permissions its job requires. Write down the account, the reason, the owner and the review date. The output is an approved exemption list. Confirm the exemption mechanism for your version in the rate limit documentation, since the way exemptions are configured can change between releases.

  5. Test throttled responses in a non-production instance

    Verify behavior on a non-production instance that mirrors the production configuration. Send requests from a test client above the configured limit to a Notes or Users API endpoint and confirm that the instance returns the throttling response you expect, and that the response is logged. Then send the same volume from an exempted service account and confirm that it is not throttled. Repeat the check for a normal user account. The check passes when throttled and exempted requests behave as the change record states, and the logs show the event with enough detail to investigate. If a legitimate integration breaks in testing, adjust the limit or exemption and repeat this step.

  6. Test each integration that calls the API

    Run the integrations you inventoried against the non-production instance under realistic call patterns. Trigger the chat, issue sync, mirroring, monitoring and automation jobs at their normal frequency, and include the busiest scheduled job if you can. Watch for errors, retries and delayed jobs, and confirm that each integration completes its work without throttling errors it does not handle. Ask each owner to sign off on their integration. The check is a written test result per integration with the outcome, the version of GitLab and the limit values in use. Any integration that fails needs either an exemption, a change to its call pattern or a documented accepted risk before production rollout.

  7. Roll out to production and monitor

    Apply the tested configuration to production through the same change process used for the non-production run, so the values and exemptions match what you tested. After the change, watch the throttling logs and the same metrics you used for the baseline, and compare them against the expected pattern. Check the integrations that matter most during their next scheduled runs. The step is complete when the production values match the change record, no unexpected throttling appears for approved callers, and the owners confirm their jobs are healthy. Keep the baseline, the test results and the exemption list in the change record so that later reviews and audits can trace each decision.

  8. Schedule periodic review of limits and exemptions

    Set a recurring review of the rate limit values, the exemption list and the caller inventory. Recheck the review whenever you upgrade GitLab, since limits, settings and documented behavior can change between releases and you should confirm the upgrade notes for each one. Remove exemptions for accounts that no longer need them, and rerun the throttling test after any change. The output is a dated review record that shows the current values, the approved exemptions and the test evidence from the last check. Ask your team to agree the review interval in advance and record it with the change process.

When to exempt service users from Notes and Users API limits

Exempt a service user only when a legitimate automated workload hits a limit that a human workflow never would. CI runners that post job status into merge requests, bots that comment on issues, sync jobs that mirror user lists from an identity provider and integrations that read the Users API at scale can all generate high Notes or Users API volume. Throttling these accounts can stall pipelines, drop comments or break provisioning, so the question is whether the traffic is expected and bounded. Before you change any setting, review the rate limit logs and identify which account, token and endpoint is responsible. If the answer is a misconfigured job that polls too often, fix the job first.

Every exemption trades availability for abuse exposure. A leaked token belonging to an exempt account can send unthrottled requests, so the exemption widens the blast radius of a credential compromise. Keep exempt accounts narrow: create a dedicated service user for each integration, give it only the project or group membership and role it needs, avoid administrator rights, and use a short-lived or rotated token where your version supports it. Do not reuse a personal account or a shared bot for several unrelated integrations, because one exemption would then cover all of them.

Record every exemption as a decision with an owner, a reason, the exact endpoint it covers and a review date. Keep the audit trail in your change management system and correlate it with GitLab audit events and the service user's activity logs, so you can show who approved the exemption and what traffic it allowed. Confirm the exemption mechanism for your installed version in the rate limit settings of the GitLab hardening recommendations and the release notes for your upgrade path, because the names of exempt roles and settings have changed between releases. Test the exemption in a staging instance first, then re-check it after every required upgrade stop.

Security and operational risks of rate limit changes

Rate limits protect GitLab from abuse, but each setting changes how legitimate traffic, attackers and your logs behave. The six risks below are the ones that most often surprise teams after they turn limits on, and each one has a monitoring or configuration check that catches it early.

Blocking legitimate CI traffic

Pipelines, mirrors and integrations often make bursts of API and Git requests that look like abuse to a limit set for interactive users. After you enable a limit, watch for failed jobs or sync errors that begin at the same time as the change. Before you tighten a value, measure normal peak request rates for your CI runners and service accounts over a representative period, then set the limit above that baseline. Test the new value in a non-production instance first where you can.

Exempt accounts as an abuse path

Exempting service users from the Notes and Users API limits removes the throttle from every credential in that account. If a token for an exempt account leaks, an attacker gets unlimited requests with the account's permissions. Keep the exempt list short, give each exempt account the narrowest role it needs, rotate its tokens on a schedule, and alert on unusual request volume from those accounts.

Limits hiding attacks

A throttle that quietly rejects excess requests can make a credential-stuffing run or scraping campaign look like a normal low-volume background. The attack succeeds in a smaller form and nobody is paged. Pair each limit with an alert on rejected requests so that sustained throttling is treated as a security event, not only as a performance nuisance, and review the source addresses behind repeated rejections.

Proxies reporting one client address

If a reverse proxy or load balancer does not pass the original client address, GitLab sees every request as coming from the proxy. One busy client can then throttle all users behind the same proxy, and an attacker can be hidden among legitimate traffic. Confirm the trusted proxy settings in your GitLab configuration, check that client addresses in access logs vary across known users, and test the behavior with a request from two different sources before you rely on the limits.

No monitoring of throttled responses

Throttled requests return HTTP 429 responses, and without collection of those responses you cannot tell whether limits are working, too strict or being probed. Confirm that your GitLab logs, reverse proxy logs and monitoring stack capture status codes by endpoint and client, and that a dashboard shows 429 rates over time. Use GitLab's logs and Prometheus metrics as the baseline, and document what a normal rate looks like before you tune anything.

Untracked configuration changes

Rate limit settings changed through the Admin Area or ad hoc edits leave no review trail, so a later incident can trace back to a change nobody remembers making. Store the settings in the same configuration management process as gitlab.rb and other hardening items, require review for each change, and record the reason, the expected effect and the rollback value. Re-check the settings after each upgrade, since changes between releases can alter defaults.

Limits to confirm in your environment

Rate limit settings only protect you if they match your GitLab version, your install method and the traffic your integrations generate. The cards below are the checks to complete before you enable limits on a production instance, and each one ties back to how the limits and exemptions behave in practice.

Exact setting names and defaults

Confirm the precise names, units and default values of each rate limit in the application settings for your installed version. Names and defaults change between releases, so a guide written for one version can point you at a setting your instance does not have. Record the current values before you change anything, so you can roll back a single setting if a build pipeline starts failing. Check the current stable version against the upgrade stops you have planned.

Edition and install method support

Confirm that your edition and install method expose each setting you plan to enable. Some controls appear only in the admin interface, while others require a change to the configuration file that your install method manages differently. Check whether a Linux package, Helm chart, Operator or Docker deployment lets you set the value and whether a change survives a reconfigure or upgrade. Ask your vendor or the install documentation to confirm this for your exact setup.

Client IP forwarding at the load balancer

Limits applied per IP address only work if GitLab sees the real client address. Behind a reverse proxy or load balancer, every request can appear to come from the same internal address, which causes legitimate users and runners to share one bucket. Confirm how your load balancer sets forwarding headers and whether GitLab trusts those headers from that proxy. Test with two clients on different networks and check which address appears in the logs.

Integrations hitting affected endpoints

Identify which automation calls the Notes and Users API endpoints before you set limits. Chat bridges, issue sync jobs, reporting scripts and custom bots can post notes or query users in bursts, and a limit that suits interactive use may stall them. Review your integration inventory and pipeline jobs, then measure request rates in a staging instance. Decide whether each integration needs an exemption or a change to how it batches requests.

Service user exemptions and access controls

Confirm exactly which accounts an exemption covers and how it behaves alongside your other access controls. A service user with an exemption still needs a scoped token, the right project role and an expiry date, and an exemption does not widen what that account can read or write. Check that the exempt account cannot be used by people for interactive sign-in, and review it during your regular access reviews. Ask your GitLab administrator to confirm how the exemption appears in the audit logs.

Monitoring and rollback behavior

Confirm how blocked requests appear to users and in your logs, and who receives the signal when limits trigger. Throttled responses can look like intermittent CI failures or API errors, so teams may retry harder and make the problem worse. Set up alerting on rejected requests, document the owner for each limit and agree on the steps to raise a limit temporarily. Test the rollback path on a staging instance before you change production.

Questions teams ask before changing GitLab rate limits

Are the default GitLab rate limits enough for most self-managed instances?

For most self-managed instances, the defaults suit typical traffic, so they are a sound starting point. The hardening guide asks teams to turn on and review each limit deliberately, because a limit that fits a small team can block CI jobs, sync tools or integrations on a busy instance. Defaults are less likely to fit when you run many API clients, large CI fleets, bulk imports, or a public-facing instance with many anonymous visitors. Before you change anything, measure your current request patterns and compare them with the limit values in your version. Read the GitLab hardening recommendations first and confirm each setting's default in your release.

How long does a GitLab rate limit change take?

No single duration applies, because the time depends on the work around the change. The main inputs are the size of the instance, how many users, API clients and integrations depend on it, whether a test environment matches production, and how much baseline traffic data you already have. A single-node instance with clean logs and a staging copy moves much faster than a larger deployment with many integrations that must be tested one by one. Ask for a timeline built from stages: inventory, baseline, testing, change window and monitoring afterward. Your position on the GitLab reference architectures scale, from 1,000 users to 50,000 users, is a useful input to any estimate.

Can our own team change GitLab rate limits without a partner?

Yes, if one or two administrators can read the hardening guidance, change settings on a test instance and review logs and API behavior afterward. The change itself is small: you set the limit values and any exemptions in the administrator settings, or in configuration files such as gitlab.rb if you manage the instance that way, then reconfigure. Confirm the exact location for your installation method and version. The harder part is judgment: deciding which limits apply to which clients, finding which CI jobs or sync tools will be affected, and showing that the change did not break a pipeline. Teams with a platform group can often do this internally, while teams without API or log expertise often ask a partner to draft the baseline and test plan. Either way, keep a rollback step ready.

What does a rate limit change need from our team?

Four inputs decide whether the change goes smoothly, and you should have them before anyone edits a setting:

  • A test environment on the same GitLab version with a similar configuration, so you can replay representative API traffic.
  • A traffic baseline from logs or monitoring that covers normal weekdays, peak CI hours and scheduled jobs.
  • Named owners for CI runners, integrations, sync tools and service accounts who can confirm their expected request volume.
  • A change window agreed with the business, a backup taken beforehand (see the GitLab backup and restore documentation) and a tested rollback step.
What would a partner include in a rate limit engagement?

A partner scope usually starts with an inventory and ends with a handover, and the written agreement fixes what is included before work begins. Typical stages are confirming the GitLab version, install method and user count; listing API clients, runners and integrations; capturing a traffic baseline; enabling limits as the hardening guide advises and documenting each value; setting exemptions for named service users; testing in a non-production copy; and running the change with monitoring and a rollback plan. Deliverables should include a settings record, a test report and an operations note for your team. Ask the partner to state what is out of scope, such as upgrades or changes to other hardening settings, so the boundaries stay clear.

How do instance size and integration count change the cost?

Cost follows the work involved, and no price for this change is given here. The main drivers are the number of GitLab environments, user count, API clients, integrations and runners, plus whether the instance runs as a multi-node or high availability topology, which adds test effort. One-time costs cover scoping, baseline analysis, testing, configuration and documentation. Recurring costs appear only if you buy ongoing review after each upgrade or when traffic changes, usually through a retainer. Ask for a quote that lists each stage and each environment separately, states what is in and out of scope and names who performs the testing. DeployOpen works from a written, fixed scope and provides a quote once that scope is agreed.

Why exempt service users from Notes and Users API limits?

Exempting a service user lets a known automation account keep its normal request volume while other clients stay under the limit. Notes and Users API traffic can be heavy for bots that post comments, sync users or read user lists, so an unexempted account may be throttled and break jobs. The trade-off is exposure: an exempt token that leaks can make many requests before anyone notices. Keep exemptions to named, least-privilege service accounts, scope their tokens, watch their request logs and review the list after staffing changes. Confirm the exact setting names and how exemptions are entered in your GitLab version before you change them.

Do rate limit settings survive GitLab upgrades?

Plan to recheck them after each upgrade, because every path to a newer version passes through required upgrade stops. Since GitLab 17.5, those stops fall at versions x.2, x.5, x.8 and x.11, for example 18.2, 18.5, 18.8, 18.11, 19.2, 19.5, 19.8 and 19.11. Test the rate limit settings on the target version as part of the upgrade plan, not after it. Compare the settings in your release notes with the values you recorded, and confirm any changed defaults in the GitLab upgrade paths documentation before the upgrade window opens.

How DeployOpen scopes GitLab hardening work

DeployOpen plans, implements, hardens and supports self-hosted open-source platforms inside the client's own infrastructure, and GitLab rate limit work is scoped the same way. DeployOpen is a Chainscore Labs company. For a rate limit change, the scope would normally cover an inventory of the current limits in the Admin area, a decision for each limit on whether to keep the default or change it, the exemption of named service users from the Notes and Users API limits, and a test plan that shows the limits do not interrupt the pipelines, bots and integrations your teams depend on. Each of these items affects a different group of people, so the written scope should name the owner of each decision, usually the GitLab administrator and the team that runs your automation.

Most engagements are fixed-scope. Scope, deliverables and timelines are agreed in writing before work starts, and a quote follows from that written scope rather than from a published price list, because DeployOpen does not publish one. When you request a quote, ask the provider to state which items are included, what evidence or change records you will receive, which tasks fall to your team, and what happens if your instance differs from the assumptions in the scope, such as a larger user count or a different authentication setup. Costs in this kind of work come mostly from the time spent on inventory, testing against real automation and documentation, so a clear list of systems in scope is the most useful input you can give.

Limit settings also change over time. New GitLab releases can adjust defaults or add controls, and the maintenance policy in the GitLab documentation sets out how each release line is supported, so a one-time change may need to be rechecked after upgrades. DeployOpen also offers retainers for ongoing support, upgrades and continuous testing, which suit teams that want the limits reviewed on each upgrade stop. DeployOpen prepares systems, settings and evidence, but it does not issue audit reports, attestations or certifications; independent auditors and certification bodies provide those. Confirm the retainer terms, review cadence and handover of documentation in writing before you commit.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.