The Symptom
Symptom
Root Cause Analysis
Root Cause
We had configured Cloudflare rate limiting on our root domain to block IPs making more than 100 requests per minute. However, an attacker realized our `/api/search?q=[term]` endpoint in Next.js (which queries an external ElasticSearch cluster) was both highly uncacheable and very slow (taking ~2 seconds per request). The attacker used a distributed botnet of 50,000 unique IP addresses to send 1 request per minute to the search API. This completely bypassed Cloudflare's per-IP rate limit. The Vercel serverless functions spun up thousands of instances, each staying alive for 2 seconds. This exhausted our concurrent execution limits, effectively causing a Denial of Service (DoS) for legitimate users, while simultaneously racking up massive per-millisecond billing charges.
5 Whys Root Cause Drill-Down
Resolution
Resolution
// The fix: Edge Middleware Rate Limiting with Upstash
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, "10 s") });
export async function middleware(request) {
const ip = request.ip ?? "127.0.0.1";
const { success } = await ratelimit.limit(ip);
if (!success) return new Response("Rate limit exceeded", { status: 429 });
}
Discussions 0