7. Rate Limits
LexVault is about to launch publicly. Alex wants safeguards so a runaway script can't burn through the project's email budget or hammer the auth endpoints.
Rate limits cap the volume of auth-related requests your project will accept per time window. They protect against credential stuffing, runaway scripts, and accidental self-DoS — without you having to write any middleware.
Every Eurobase project gets a sane platform-wide default. You only need to touch this page if you want to tighten or loosen a specific knob.
Where to find it
In the console: Auth → Rate Limits tab. The page mirrors the same five knobs Supabase users will recognise, plus an "IP Address Forwarding" toggle for projects behind a CDN.
The six knobs
- Signup / sign-in rate — how many
/v1/auth/signup+/v1/auth/signinrequests per 5-minute window per IP. Default: 8 per 5 min. - Token refresh rate — how many
/v1/auth/refreshcalls per 5 min per IP. Higher than the others because legitimate SDK clients refresh proactively. Default: 150 per 5 min (~ 1800/hour). - Token verification rate — how many OTP / magic-link verify calls per 5 min per IP. Default: 30 per 5 min.
- Emails per hour — cap on outbound auth emails (verification, password reset, magic link) the project sends through the platform sender per rolling hour. Default: 2/hour. When you bring your own SMTP (next chapter), sends through your provider are not counted against this cap.
- SMS per hour — cap on outbound auth SMS (phone OTP) per rolling hour. Default: 30/hour.
- IP Address Forwarding (Trust Proxy) — when on, the rate limiter uses the leftmost
X-Forwarded-Forentry as the client IP instead of the TCP peer. Turn this on if your app sits behind a CDN or reverse proxy that you control; leave it off otherwise. Default: off.
Zero means default, not zero
Saving an empty input or a literal 0 resets that knob to the platform default. The form is designed so you can't accidentally lock yourself out by typing 0 in "emails per hour" and then waiting a week wondering why signups aren't arriving.
Setting them up
- Open Auth → Rate Limits.
- For each knob, leave blank to keep the platform default, or enter your value. The placeholder text shows what the default is.
- (Optional) Toggle IP Address Forwarding if your app is behind a CDN/proxy. Only do this if you know your edge stack rewrites
X-Forwarded-For— otherwise an attacker can spoof the IP and dodge the limit. - Hit Save changes. The new limits apply within a few seconds — no redeploy needed.
What an over-quota response looks like
When a project exceeds a per-IP rate, the SDK receives HTTP 429 Too Many Requests with a Retry-After header naming the number of seconds the client should wait. Your app can surface a friendly message; the limit window slides, so retrying after the indicated delay succeeds.
// SDK example: handle 429 cleanly
try {
await eb.auth.signIn({ email, password })
} catch (err) {
if (err.status === 429) {
const retryAfter = parseInt(err.headers['retry-after'] || '60', 10)
showToast(`Too many attempts. Try again in ${retryAfter}s.`)
return
}
throw err
}Tuning guidance
- Just launched, small audience. Leave the defaults — they're set for a project receiving up to a few thousand signups/day.
- Growing fast, lots of token refreshes. Raise the token-refresh knob if you see legitimate 429s. The default (~1800/hour/IP) handles most SDK clients, but if your app refreshes more aggressively, double or triple it.
- Phone-first product (SMS OTP). Raise SMS/hour to your provider quota. The default is conservative so an accidental script doesn't bleed your GatewayAPI budget.
- Outgrowing the platform email cap. See the next chapter (Custom SMTP) — bringing your own SMTP provider removes the platform "emails per hour" cap entirely for sends through your provider.
What rate limits don't do
These knobs only cap auth-flow traffic. They do not gate your SDK reads/writes against the database or storage — those are governed by your plan's request budget (Settings → Usage). For application-level rate limiting on your own endpoints, build it into your edge functions or your app middleware.