00 / guide
Supabase "email rate limit exceeded" (over_email_send_rate_limit): the limits and how to raise them
A new user signs up, asks for a magic link or resets a password, and your app shows an error instead of sending the email. People search for it as “email rate limit exceeded”. Supabase's docs list it by its error code, over_email_send_rate_limit, and answer with HTTP 429 when a rate limit is hit. Supabase: Auth error codes Here are the limits as Supabase documents them today, and how custom SMTP lets you raise them.
01 / what CheckoutAlarm checks
a
What it would catch here
Nothing on this page. CheckoutAlarm doesn't see Supabase Auth emails, and it never sees your Auth errors.
b
What it won't catch
It doesn't sign up, log in or read inboxes. It loads one page you pick and reads Stripe with a read-only key, so it can't tell you that sign-up emails are being refused.
c
Plans
Free: 1 site, checked once a day. Pro: $19 a month, up to 3 sites checked hourly. You prove you own the site first. For Stripe we only take a restricted key with read access to Events, Webhook Endpoints and Charges. Full secret keys are refused. Compare plans
Free tool: which kind of Stripe key you have (CheckoutAlarm only takes a read-only restricted key)
02 / what the error means
1
The error code
Supabase describes over_email_send_rate_limit as: “Too many emails have been sent to this email address. Ask the user to wait a while before trying again.” Supabase: Auth error codes
2
Check the code, not the text
Errors from the Auth API come back as AuthApiError with a code and an HTTP status. Supabase's advice: “Always use error.code and error.name to identify errors, not string matching on error messages.” So test for error.code === "over_email_send_rate_limit" and show the user a “please wait and try again” message. Supabase: error handling
03 / which limit you hit
1
The project-wide email limit
Supabase's rate limits table lists emails sent by Supabase Auth as limited by project, across all email-sending Auth endpoints: “2 emails per hour with the built-in email provider. You can configure this limit when you use custom SMTP or the Send Email hook.” Supabase: Auth rate limits The custom SMTP page adds that this value “can change without notice” and that the built-in server has no delivery guarantee. Supabase: custom SMTP
Those 2 emails an hour are shared by every email-sending Auth endpoint in the project, such as sign-up confirmations, magic links and password resets. Your own test sign-ups count too.
2
The 60-second wait per user
Sign-up confirmation (/auth/v1/signup), magic links and OTPs (/auth/v1/otp) and password resets (/auth/v1/recover) each default to “a 60 seconds window before a new request is allowed for the same user.” Supabase: Auth rate limits A user who presses “resend” twice in a row hits this even when the hourly limit has room. Magic links and OTPs also expire after 1 hour by default. Supabase: passwordless email sign-in
3
Not the same: the per-IP request limit
Sign-ups and sign-ins (/signup, /recover, /resend, /magiclink, /otp, /user) are also limited by IP address: by default 30 requests per 5 minutes, with bursts up to 30. Supabase: Auth rate limits Going over that returns over_request_rate_limit, which Supabase says can indicate a bug that sends too many requests, “such as a badly written useEffect React hook”. Supabase: Auth error codes
04 / fix: custom SMTP lifts the email limit
1
Add your own SMTP server
Supabase works with any service that speaks SMTP; its list includes Resend, AWS SES, Postmark, Twilio SendGrid, ZeptoMail and Brevo. You need the host, port, user, password and a From address, then you turn on custom SMTP in the Authentication settings. Supabase: custom SMTP For Resend that is host smtp.resend.com, port 465, username resend and your Resend API key as the password, with a verified domain first. Resend: send with Supabase SMTP Full setup: Supabase confirmation email not arriving.
2
Expect 30 an hour at first
Once you save, Supabase sends to all addresses, and “to protect the reputation of your newly set up service a low rate-limit of 30 messages per hour is imposed.” Supabase: custom SMTP
3
Raise it to what you need
Open Authentication, then Rate Limits, in your project and set the email limit. You can also read and change it with the Management API at /v1/projects/<ref>/config/auth, using the rate_limit_email_sent field. Supabase: Auth rate limits Your email service has its own limits too; Supabase suggests talking to it before a planned surge. Supabase: prepare for large surges
4
Or use a Send Email hook
The Send Email hook replaces Supabase's built-in email sending with your own code. When the email provider and the hook are both enabled, the hook sends the email and SMTP isn't used. Supabase: Send Email hook With a hook, the email limit is configurable too. Supabase: Auth rate limits
05 / stop burning the limit
1
Test emails locally
The Supabase CLI captures emails sent locally with Mailpit. Run supabase status to get the Mailpit URL and read the emails there. Supabase: local development with Mailpit
2
Send the email only on a click
If sign-in or “resend” runs inside a useEffect or on every render, each run asks for a new email. Make sure the call only runs when the user presses the button, and disable the button for 60 seconds after a send to match the per-user window. Supabase: over_request_rate_limit Supabase: 60-second window
3
Server-side calls share one IP
If your server or a proxy calls Supabase Auth for every user, all requests can count against your server's IP. Supabase lets you enable IP address forwarding under Authentication, Rate Limits, then send the user's IP in the Sb-Forwarded-For header with a secret API key (publishable and legacy anon/service_role keys are not supported). Supabase: IP address forwarding
4
Fewer forced sign-ins
Short sessions make active users sign in again, which means more emails. Supabase suggests longer sessions, and if you use an SSR framework, checking that your middleware doesn't end sessions early. Supabase: increase the duration of user sessions
06 / if bots are using it up
1
Turn on CAPTCHA
Supabase names bots signing up lists of email addresses as a common source of abuse, and calls CAPTCHA protection “the most effective way to control bots in this scenario.” Supabase: dealing with abuse
2
Keep email confirmations on
Supabase's advice is: “Do not disable email confirmations under pressure.” Turning them off is one of the outcomes attackers push for. Supabase: mitigation strategies If emails now send but land in spam, see emails sent with Resend going to spam.
07 / questions
- What is Supabase's email rate limit?
- With the built-in email provider, Supabase's rate limits page lists 2 emails per hour, counted per project across all email-sending Auth endpoints. Supabase says this value can change without notice. Separately, sign-up confirmation, magic link or OTP, and password reset requests each default to a 60-second wait for the same user.
- Can I raise the email limit without custom SMTP?
- No. The rate limits page says you can configure the email limit when you use custom SMTP or the Send Email hook. With the built-in provider it stays at 2 emails per hour.
- What is the limit right after I add custom SMTP?
- Supabase sets a low limit of 30 messages per hour to protect the reputation of your new sender. You can change it on the Rate Limits page (Authentication, then Rate Limits) or with the rate_limit_email_sent field in the Management API.
- What's the difference between over_email_send_rate_limit and over_request_rate_limit?
- over_email_send_rate_limit is about emails: too many were sent to this address. over_request_rate_limit is about requests from one IP address, for example more than the default 30 sign-up or sign-in requests per 5 minutes. Supabase notes that the second one can point to a bug, such as a badly written useEffect hook.
- Does CheckoutAlarm catch this error?
- No. CheckoutAlarm loads one page you pick and reads Stripe with a read-only key. It doesn't sign up, log in or read email, so it never sees a Supabase Auth error.
08 / where CheckoutAlarm fits
CheckoutAlarm won't catch this. It loads one page you pick and reads Stripe with a read-only key. It doesn't sign up or read email, so it never sees a Supabase email rate limit error.
CheckoutAlarm is new. It only checks sites you prove you own. How to verify
Watch my app free09 / sources
- Supabase: Auth rate limits (2 emails per hour built-in; 60-second per-user window; per-IP limits; IP forwarding)
- Supabase: Auth error codes (over_email_send_rate_limit, over_request_rate_limit, 429)
- Supabase: send emails with custom SMTP (30 messages per hour after setup; abuse and best practices)
- Supabase: Send Email hook
- Supabase: passwordless email sign-in (once every 60 seconds; links expire after 1 hour)
- Supabase: password-based auth (local development with Mailpit)
- Resend: send emails using Supabase with SMTP
Docs checked on Oct 23, 2026.