- 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
For the full self-hosted upgrade checklist, use this page together with the
v5 migration guide.
- 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)
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 JSON429s
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-levelapi.clientlimiter)GET /api/v2/health(not rate-limited)OPTIONSrequests (not rate-limited)
429 Response Shape
Application-generated v1429s return:
429s return:
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: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.