Router Rate Limiting Runbook

Last updated: 2026-05-30

Audience: platform operators rolling out, tuning, or troubleshooting Stella Ops Router rate limiting. For the configuration schema and field reference, see Router rate-limiting configuration.

Purpose

Preconditions

Rollout plan (recommended)

  1. Dry-run wiring: enable rate limiting with limits set far above peak traffic to validate middleware order, headers, and metrics.
  2. Soft limits: set limits to ~2× peak traffic and monitor rejected rate and latency.
  3. Production limits: set limits to target SLO and operational constraints.
  4. Migration cleanup: remove any remaining service-level HTTP rate limiters to avoid double-limiting.

Response semantics (what a rejected client sees)

When a request is denied the Router responds with 429 Too Many Requests and:

The scope field/tag is the rate-limit scope (instance vs environment), not an OAuth scope. The rate-limit middleware performs no scope/permission authorization of its own.

Tenant partitioning

The limiter key is partitioned by tenant when the request is authenticated: the gateway reads the first of the stellaops:tenant, tenant, or tid claims and prefixes the partition as <tenant>|<microservice>. Anonymous / tenant-less requests share a default partition keyed by microservice alone. Consequence: one tenant’s burst cannot 429 another tenant’s traffic to the same microservice. The tenant prefix is opaque to the counters — it is just part of the key.

Monitoring

Key metrics (OpenTelemetry)

Caveat — rejected is double-counted. A denied request increments stellaops.router.ratelimit.rejected twice: once on the per-decision path (RateLimitService.RecordDecision(..., allowed: false)) and again on the middleware reject path (RateLimitMiddlewareRecordRejection). allowed increments only once. Treat rejected as ~2× the true reject count and use it for trend/alerting rather than as an exact request count; the deny-ratio formula below therefore overstates the ratio. (Source: RateLimitService.cs:62,90 + RateLimitMiddleware.cs:81.)

PromQL examples

Incident response

Sudden spike in 429s

Valkey unavailable / circuit breaker opening

Troubleshooting checklist

Load testing