Sign-in rate limits
Each protected action is counted twice over a rolling 15-minute window: once per email address and once per IP address. Whichever limit is reached first refuses further requests until the window moves on.
The sign-in limits are loose on purpose: they stop credential stuffing and mail bombing, and an office behind one shared address should never reach them.
With
REDIS_URL set, as in every standard install, the counters live in Redis and are shared by every backend. Without Redis, each process counts on its own. The backend logs which at start, for example Abuse guard using Redis counters (shared across instances). If Redis becomes unreachable, requests are let through rather than locking everyone out.
Change the limits
Every number can be set. The variable isGUARD_ + the action’s name in capitals + _EMAIL or _IP:
GUARD_WINDOW_MS is the window in milliseconds. 0 turns off that count, so GUARD_LOGIN_IP=0 stops counting sign-ins per IP while still counting them per email.
Add a captcha
Cloudflare Turnstile can be required before an action goes through. It is off until you set it up.1
Create a Turnstile widget
In the Cloudflare dashboard, add a Turnstile widget for your domain. You get a site key and a secret key.
2
Set both keys
3
Choose the actions it guards
By default only
otp_request asks for the captcha. List others by name, separated by commas:Passwordless sign-in
true, and it needs working email: without a provider the codes never arrive and nobody can sign in.
Public API and upload caps
Separate from the sign-in limits, two hourly caps apply per workspace:
They are counted separately, so a folder of files added to the media library never uses up the posting cap. The other public API routes and posts made in the app are not counted. With Redis, the counts are shared by every backend. A request over the cap is answered with
429: see Limits and errors.
Farcaster signer routes
Connecting Farcaster uses two public routes: one creates a Neynar managed signer, the other checks whether the person approved it. Both are limited per client address, with numbers fixed in the code:
The client address is the last entry of the
X-Forwarded-For header, the one added by the nginx inside the container, so a client cannot choose its own count by sending the header. Behind a reverse proxy of your own, that last entry is the proxy’s address as the container sees it. Everyone then shares one count, which allows 30 new Farcaster connections per hour across the whole install.
Related
- Deploy to a server:
DISABLE_REGISTRATIONcloses sign-up entirely - Email: needed for passwordless sign-in and password resets
- Configuration reference