- 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 and invitation budgets)
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:
Invite limits count successfully created or refreshed invites. A bulk request for 25 people consumes 25 units
only when all 25 invites are created; recipients who are already members, already invited, or otherwise fail do
not consume the daily budget. Self-hosters can change the limit with
INVITE_RATE_LIMIT_PER_24_HOURS;
Formbricks Cloud organizations with the bulk-invite entitlement receive a limit of 500 recipients.
The same allowance also applies to each inviting user across all of their organizations, so creating another
organization does not reset it.
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.