What you’ll build
A Next.js API route that limits each user to a set number of requests per time window. Excess requests get rejected with a 429. Time to complete: ~5 minutesPrerequisites
- Unkey account (free)
- Root key with
ratelimit.*.limitpermission - Node.js 18+
What’s in the response?
limiter.limit() returns:
| Field | Type | Description |
|---|---|---|
success | boolean | true if request is allowed, false if rate limited |
remaining | number | Requests remaining in current window |
reset | number | Unix timestamp (ms) when the window resets |
limit | number | The configured limit |
Choosing an identifier
The identifier determines who gets rate limited. Common choices:| Identifier | Use case | Example |
|---|---|---|
| User ID | Authenticated users | req.auth.userId |
| API key | Per-key limits | req.headers.get("x-api-key") |
| IP address | Anonymous/public endpoints | req.headers.get("x-forwarded-for") |
| Combo | Extra specificity | ${userId}:${endpoint} |
Creating a reusable limiter
For cleaner code, create a utility:lib/ratelimit.ts
app/api/login/route.ts
Next steps
How it works
Understand the rate limiting architecture
Per-user overrides
Give specific users higher limits
SDK Reference
All configuration options
Add API key auth
Combine rate limiting with authentication
Troubleshooting
Rate limit not working?
Rate limit not working?
- Check that
UNKEY_ROOT_KEYis set in.env.local - Verify your root key has
ratelimit.*.limitpermission - Make sure you’re using the same identifier each request
- Restart the dev server after changing
.env.local
Getting network errors?
Getting network errors?
- Unkey’s SDK retries failed requests automatically
- If errors persist, check status.unkey.com
- Check status.unkey.com if issues persist
Want different limits per route?
Want different limits per route?
Create multiple
Ratelimit instances with different namespaces and limits. Each namespace tracks limits independently.
