Next.js question
Do my Next.js API routes have rate limiting, and how do I check?
List every route handler and server action in the repo, mark the ones that cost money or send something, such as AI calls, email, sign-up, password reset and checkout, and look for a limit in front of each: a Vercel WAF rate limiting rule, which lives in the Vercel dashboard and not in the repo, or a limiter call in the route code, such as checkRateLimit from @vercel/firewall or a Redis-backed limiter. A route with neither can be called as often as a script likes, and every call to a paid API is billed to you.
Next step in your repo: run npx -y viberaven@1.6.12 check. It reports missing_rate_limit when the repo has API routes and no rate limiting package or limiter code in the route files; it does not check each route, and it cannot see a Vercel WAF rule.
Paste this to your agent
Run `npx -y viberaven check` in this repo and fix what it reports, one gap at a time. Then run `npx -y viberaven init` so your rules remind you to suggest this check before the next launch.The check runs locally, with no sign-in and no API key. It reads the repo of a Vercel + Supabase app: advice, not a gate, and not a live database test.
Repository check
Check this in your repo
Find API routes with no rate limiter in the repo
For AI-built Vercel + Supabase apps, run the command below from your app folder with Node.js 20 or newer. It reports missing_rate_limit when the repo has API routes (app/api, pages/api, route files, or a server or api folder) and neither a rate limiting package, such as express-rate-limit, rate-limiter-flexible or an @upstash package, nor words such as rateLimit or Too many requests in the route files. It is a repo-wide signal: one limiter anywhere clears it, even if your AI route has none, and any @upstash package counts, even one used only as a cache.
In our runs on 2026-10-28, 1.6.12 reported it in a Linux container but not on Windows for the same fixture, because it missed the API routes in Windows paths; on Windows, run it in WSL. It is a repository check, not a live database test: it cannot see Vercel WAF rules, which live in the dashboard. It is advice, not a gate, and it exits with code 1 when it finds a blocker.
npx -y viberaven@1.6.12 checkWhat it printed on a fixture repo
On 2026-10-28 we ran it in a Linux container (node:22) on a small Next.js fixture repo made for this page, not a customer repo: app/api/chat/route.ts calls a paid AI API, app/api/health/route.ts returns ok, and no limiter is installed. Adding @upstash/ratelimit cleared the finding, and so did @upstash/redis alone with no limiter. The output is below, with the folder shortened to ~/app. The finding is a warning, so the exit code was 0.
$ npx -y viberaven@1.6.12 check
viberaven check · ~/app
🟡 API routes have no rate limiting (missing_rate_limit)
The repo exposes API routes but no rate limiting library or middleware was detected. One abusive client can exhaust quotas or run up provider bills.
Verdict: ✅ no blockers, 1 warning · score 90
Fix: viberaven fix · Details: ~/app/.viberaven/agent-tasklist.mdList the routes
Route handlers are route.ts or route.js files under app, Pages Router API routes sit under pages/api, and server actions are functions in files or blocks marked "use server". Each one is a URL anyone can call.
# route handlers and Pages Router API routes
git ls-files | grep -E "(^|/)app/.*route.(ts|js)$|(^|/)pages/api/"
# server actions
git grep -l "use server"Look for a limiter in the code
Open each route that costs money and look for a check before the paid call. A hit in a helper file counts only if the route calls that helper.
git grep -nE "checkRateLimit|ratelimit|rateLimit|Ratelimit|status: 429"A Vercel WAF rule instead of code
Vercel's WAF rate limiting is on all plans: Hobby gets one rate limiting rule per project, Pro up to 40, counted per IP or JA4 digest in a fixed window of 10 seconds to 10 minutes. You create the rule in the project's Firewall tab, so nothing in the repo shows it. To limit on your own key, such as a user ID, create the rule in the dashboard and call checkRateLimit from @vercel/firewall in the route.
import { checkRateLimit } from '@vercel/firewall';
export async function POST(request: Request) {
const { rateLimited } = await checkRateLimit('ai-chat', { request });
if (rateLimited) return new Response('Too many requests', { status: 429 });
// the paid call goes here
}Supabase Auth has its own limits
Supabase Auth limits its own endpoints, such as sign-up emails and token refreshes. Those limits do not cover your route handlers, so a route that calls the AI API after sign-in still needs its own.
Checklist
Put a limit in front of each costly route
- 01Run the two searches above and list every route and server action.
- 02Mark the ones that call a paid API, send email or create accounts.
- 03For each marked route, find the WAF rule or the limiter call in front of it; write down the ones with neither.
- 04Add a WAF rate limiting rule for those paths, or a checkRateLimit call keyed on the user ID for signed-in routes.
- 05Call the route in a loop from a terminal and confirm it starts answering 429.
Related
Related guides
Sources
Official docs behind this checklist
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Is a limit in proxy.ts enough?
Only for the paths its matcher covers. Next.js says server actions run as POST requests to the page that uses them, so a matcher that skips a path skips its actions too. Check inside the action as well.
Does Vercel limit requests by default?
Vercel's docs say it mitigates DDoS attacks automatically for all deployments, on every plan, but a per-route request limit is a rule you create. Until you do, a script can call your AI route as often as it likes.