Problem
@fastify/rate-limit is registered with global: false and only applied to WHIP/WHEP POST endpoints (10 req/min each). The high-frequency polling endpoints have no server-side rate limits:
GET /api/v1/heartbeat/:sessionId
GET /api/v1/production/:id/line/:lineId
POST /api/v1/production/:id/line/:lineId/participants (long-poll)
POST /api/v1/session
POST /api/v1/reauth
Additionally, since 401 errors are returned at the nginx ingress auth_request layer (before requests reach Fastify), the app-level rate limiter is completely bypassed for unauthenticated requests.
Proposed solution
Option A (simpler): Enable rate limiting globally by changing global: false to global: true with sensible defaults (e.g., 60 req/min per IP), and keep the stricter WHIP/WHEP limits as overrides.
Option B (granular): Add per-route rate limit configs to the polling endpoints:
heartbeat: 10 req/min (expected cadence is 6/min)
fetchProductionLine: 90 req/min (expected cadence is 60/min, with headroom)
participants long-poll: 10 req/min (expected cadence is ~2.4/min at 25s cycles)
reauth: 5 req/min
session: 10 req/min
Note: This protects against misbehaving clients that pass auth, but does NOT stop 401 floods (which are rejected before reaching Fastify). See the companion nginx ingress rate limiting issue for edge-level protection.
Priority
Short-term
Context
See investigation in #internal-dev-intercom (2026-02-28).
Problem
@fastify/rate-limitis registered withglobal: falseand only applied to WHIP/WHEP POST endpoints (10 req/min each). The high-frequency polling endpoints have no server-side rate limits:GET /api/v1/heartbeat/:sessionIdGET /api/v1/production/:id/line/:lineIdPOST /api/v1/production/:id/line/:lineId/participants(long-poll)POST /api/v1/sessionPOST /api/v1/reauthAdditionally, since 401 errors are returned at the nginx ingress auth_request layer (before requests reach Fastify), the app-level rate limiter is completely bypassed for unauthenticated requests.
Proposed solution
Option A (simpler): Enable rate limiting globally by changing
global: falsetoglobal: truewith sensible defaults (e.g., 60 req/min per IP), and keep the stricter WHIP/WHEP limits as overrides.Option B (granular): Add per-route rate limit configs to the polling endpoints:
heartbeat: 10 req/min (expected cadence is 6/min)fetchProductionLine: 90 req/min (expected cadence is 60/min, with headroom)participantslong-poll: 10 req/min (expected cadence is ~2.4/min at 25s cycles)reauth: 5 req/minsession: 10 req/minNote: This protects against misbehaving clients that pass auth, but does NOT stop 401 floods (which are rejected before reaching Fastify). See the companion nginx ingress rate limiting issue for edge-level protection.
Priority
Short-term
Context
See investigation in
#internal-dev-intercom(2026-02-28).