Remove Labkit rate limiter feature flags, collapse to always-on
What does this MR do?
Removes the cohort 1-6 Labkit::RateLimit migration feature flags and collapses Gitlab::ApplicationRateLimiter onto the labkit path as the sole, authoritative rate limiter. With the migration fully enforced on .com, the dual-path machinery is no longer needed.
Removed:
- The 20
rate_limiter_use_labkit_*and*_enforcewip flag YAMLs (cohorts 1-6). - The legacy Redis counter path (
legacy_throttled?, theapplication_rate_limiter:*key shape, the strategy dispatch through it). - The shadow comparison (
record_divergence,gitlab_rate_limiter_labkit_shadow_total) and the boundary-noise tagging. - The override-to-legacy routing (
override_routes_to_legacy?,record_override,gitlab_rate_limiter_labkit_override_total). Per-callthreshold:/interval:overrides are now honoured by labkit through the Rule'srule_contextlambdas. - The
gitlab_application_rate_limiter_throttle_utilization_ratiohistogram (legacy-path only). - The now-dead
flag_scope:registry metadata (the per-key/cohort flag mapping, unread once the flags are gone), the EE spec examples that asserted it, and the comments describing the removed flag/shadow machinery.
LabkitAdapter is now flag-free: shadow_or_enforce?, enforce?, and flag_basis are gone, replaced by handled? (registry membership). _throttled? returns labkit's decision directly.
Guardrail
Because there is no legacy fallback, a rate_limits key with no registry entry would no longer be rate limited at all. A new spec asserts every ApplicationRateLimiter.rate_limits key has a SupportedRateLimits entry, so a new key can't silently bypass rate limiting. As part of that, this MR registers the previously-unregistered keys token_exchange and project_generate_new_export, plus placeholder_reassignment, a key added to rate_limits on master after this branch forked that the guardrail flagged on the merge ref.
Reviewer notes
- Merge ordering / overlap: the
token_exchangeandproject_generate_new_exportregistry entries are also added by !239752 (merged) and !239753 (merged). A rebase/conflict against whichever merges first is expected. Separately,placeholder_reassignmentwas added torate_limitson master after this branch forked; it is registered here ahead of the rebase so the guardrail stays green on the merge ref. - Metric removal:
gitlab_application_rate_limiter_throttle_utilization_ratiois removed. Any Grafana panel or alert still keyed on it must be migrated to the labkit metrics (gitlab_labkit_rate_limiter_*) before this merges. - Dropped window specs: examples that asserted counter reset after the interval via
travel_toare removed. Window expiry is now labkit's Redis-TTL behaviour, whichtravel_tocannot drive; it is covered by labkit's own specs. resource:callers: verified the only caller passingresource:(the git-abuseBaseThrottleService) uses theunique_project_downloads_*keys, which arecount_distinct(set-mode) and remain handled.- Follow-up (not in this MR): the legacy strategy Redis methods (
BaseStrategy,IncrementPerAction#increment/#read, etc.) are now dead but still referenced for dispatch type-routing; slimming them is left to a separate MR to keep this one focused.
Do not merge until
- Cohort 5 (
*_db_duration_*, gitlab-com/gl-infra/production-engineering#28812 (closed)) fully enforced on .com. Satisfied (2026-06-11): all cohorts 1-6 are enforced on .com and the shadow path wound down ~June 9, so labkit is already authoritative for these keys; removing the flags no longer changes runtime behaviour.
Verification
Ran locally against the GDK (Redis + Rails): the rewritten application_rate_limiter_spec, labkit_adapter_spec, both supported_rate_limits_specs, and web_hooks/rate_limiter_spec all pass, plus the guardrail spec under FOSS_ONLY=1. RuboCop clean on changed files.
References
- Cleanup issue: gitlab-com/gl-infra/production-engineering#28876
- Epic: gitlab-com/gl-infra#2021