Skip to main content
Formbricks applies request rate limits to protect against abuse and keep API usage fair. Starting with Formbricks v5, rate limiting is split across two layers:
  • Envoy Gateway for public and API-key routes that can be enforced at ingress
  • The application server for remaining session-authenticated routes, server actions, and other flows Envoy does not currently cover
Formbricks v5 removes application-level rate limiting for several routes that are now expected to be protected by Envoy Gateway. If you self-host Formbricks without Envoy or an equivalent edge rate limiter, those routes will no longer be throttled by the application server after upgrading.
For the full self-hosted upgrade checklist, use this page together with the v5 migration guide.
Rate limits are scoped by identifier, depending on the endpoint and enforcement layer:
  • IP hash (for unauthenticated/client-side routes and public actions)
  • API key ID (for Envoy-managed and app-managed authenticated API calls)
  • User ID (for authenticated session-based calls and server actions)
  • Organization ID (for follow-up email dispatch)
When a limit is exceeded, the API returns 429 Too Many Requests.

v5 Migration Note

Before upgrading to Formbricks v5:
  • deploy Envoy Gateway or an equivalent edge rate limiter for the covered routes below
  • keep application Redis/Valkey enabled for the remaining app-enforced limits
  • expect covered routes to emit gateway 429s instead of the legacy app JSON 429s
For the current source of truth on covered routes and thresholds, use this page together with your deployment configuration and the v5 migration guide.

Envoy-Managed Limits

These limits are expected to be enforced at the gateway layer in Formbricks v5 and later: Session-authenticated /api/v1/management/*, /api/v1/management/me, /api/v1/management/storage, and DELETE /storage/... requests are not covered by the current Envoy policies and remain app-enforced.

App-Enforced Limits

These are the limits that still run inside the Formbricks application server:

Explicit Envoy Exclusions

The current Envoy policy set explicitly excludes these routes:
  • GET /api/v1/client/og (still covered by the app-level api.client limiter)
  • GET /api/v2/health (not rate-limited)
  • OPTIONS requests (not rate-limited)

429 Response Shape

Application-generated v1 429s return:
Application-generated v2/v3 429s return:
Envoy-generated 429s are gateway responses and should include an x-envoy-ratelimited header. Their exact body shape is not the same stability contract as the in-app JSON responses above.

Disabling Rate Limiting

For self-hosters, rate limiting can be disabled if necessary. We strongly recommend keeping it enabled in production. Set:
After changing this value, restart the server. This setting disables only the application-level limiter. It does not disable Envoy rate-limit policies.

Operational Notes

  • Redis/Valkey is required for the application-level limiter (REDIS_URL).
  • If you deploy Envoy rate limiting, use a dedicated Redis/Valkey backend for Envoy instead of sharing the app cache.
  • If application Redis is unavailable at runtime, app rate-limiter checks currently fail open (requests are allowed through without enforcement).
  • Client storage upload rate limits count signed upload URL issuance, not successful object creation in S3-compatible storage.
  • Authentication failure audit logging uses a separate throttle (shouldLogAuthFailure()) and is intentionally fail-closed: when Redis is unavailable or errors occur, audit log entries are skipped entirely rather than written without throttle control. This prevents spam while preserving the hash-integrity chain required for compliance. In other words, if Redis is down, no authentication-failure audit logs will be recorded—requests themselves are still allowed (fail-open rate limiting above), but the audit trail for those failures will not be written.