Verified Commit 04c7f003 authored by Bob Van Landuyt's avatar Bob Van Landuyt 💬
Browse files

docs: clarify limiter name collisions across services

Address Hercules' question about who provides the limiter name and
what happens when two services share one.

- In Phase 1, note that limiter names are static per-application
  configuration declared in `available_limiters`, so two limiters in
  the same service cannot collide. Names can repeat across services
  harmlessly because each service counts in its own Redis storage.
- In Phase 3, call out that the external service keys on the limiter
  name and must scope rules by the calling service too, so a dynamic
  rule for one service cannot leak into another that shares the name
  (most relevant for the generic limiters).

gitlab-com/gl-infra/production-engineering#28775
parent 32efab45
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -76,8 +76,15 @@ limiter = Labkit::RateLimit::Limiter.new(
result = limiter.check(identifier)
```

The `name` is prepended to all Redis counter keys, so different limiters never
share counters.
The `name` is prepended to all Redis counter keys, so different limiters within
a service never share counters. Limiter names are static per-application
configuration, declared in that service's `available_limiters` (Phase 2), so two
limiters in the same service cannot accidentally collide.

Names can repeat across services: `rack_request` may exist in several, and that
is harmless. Each service counts in its own Redis storage (for GitLab Rails,
the dedicated rate-limiting Redis), so a shared name never means a shared
counter.

### 1.2 Language SDKs

@@ -761,6 +768,13 @@ The service receives the rate limiter name and the identifier. Between them,
these carry everything the service needs to make a decision: the rate limiting
checkpoint, request type, user, namespace, plan, endpoint.

Because the service keys on the limiter name, it has to account for the same
name meaning different things in different services. This matters most for the
generic limiters (Rack middleware, gRPC interceptors), where `rack_request` is
reused everywhere on purpose. The service scopes rules by the calling service as
well as the limiter name, so a dynamic rule meant for one service does not leak
into another that happens to share the name.

### 3.2 Capabilities

Per-namespace and per-plan thresholds are already possible in Phase 2 through