Skip to content

Add rate limiting to heartbeat, line-polling, and participants endpoints #201

@birme

Description

@birme

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions