Replace Next.js/Supabase/Vercel stack with a self-hostable setup: Vite+React frontend, Fastify+Drizzle+PostgreSQL backend with own JWT auth, deploy via git pull + rsync + systemd (checkout/service separated, updates pulled from Gitea). Adds a reference auth route (register/login/me) as the canonical pattern for new routes. Updates all skills/rules/agents/docs to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BMdBJfD9TT6XUU2NqGG1PN
1.6 KiB
1.6 KiB
Rate Limiting
Prevent abuse, brute-force, and excessive API usage.
When to Add Rate Limiting
- MVP: Optional (focus on features first)
- Production with users: Recommended on auth endpoints and public APIs
- Public-facing APIs: Required
Setup with @fastify/rate-limit
No external service needed — in-memory by default, works fine for a single backend instance.
1. Install Dependency
cd backend && npm install @fastify/rate-limit
2. Register Globally
// backend/src/server.ts
import rateLimit from "@fastify/rate-limit";
await app.register(rateLimit, {
max: 100,
timeWindow: "1 minute",
});
3. Tighter Limits on Specific Routes
// backend/src/routes/auth.ts
app.post("/api/auth/login", {
config: {
rateLimit: { max: 5, timeWindow: "1 minute" },
},
}, async (request, reply) => {
// login handler
});
4. Response on Limit Exceeded
@fastify/rate-limit returns HTTP 429 automatically with Retry-After and X-RateLimit-* headers — no manual handling needed.
Recommended Limits
| Endpoint Type | Limit | Window |
|---|---|---|
| Login/Register | 5 requests | 1 minute |
| Password Reset | 3 requests | 5 minutes |
| General API | 30 requests | 10 seconds |
| File Upload | 5 requests | 1 minute |
Multi-Instance Deployments
If the backend ever runs as more than one process/instance behind a load balancer, switch the plugin's store to Redis (@fastify/rate-limit supports a custom redis client option) so limits are shared across instances instead of per-process.