Stop surprise $1,000+ Vercel invoices: configure Cloudflare WAF, edge middleware Upstash rate limits, Stale-While-Revalidate headers, and hard spend caps.
import { NextRequest, NextResponse } from "next/server";
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(60, "1 m"), // 60 requests / minute
analytics: true
});
export async function middleware(req: NextRequest) {
const ip = req.ip ?? "127.0.0.1";
const { success } = await ratelimit.limit(ip);
if (!success) {
return new NextResponse("Too Many Requests - Rate Limit Exceeded", { status: 429 });
}
return NextResponse.next();
}
Vercel's developer ergonomics are unmatched, but its billing architecture is an unmetered utility: if your application is targeted by an unmitigated Distributed Denial of Service (DDoS) attack or an aggressive AI scraping bot army, Vercel will process the requests and bill your credit card for every gigabyte of bandwidth ($0.15/GB) and serverless function execution ($0.40/1M invocations).
Securing a Next.js application on Vercel requires positioning Cloudflare as an edge proxy (Orange Cloud) in front of Vercel to absorb Layer 7 floods, filter rogue AI crawlers, and drop malicious traffic before it ever touches Vercel's billed edge network.
| Attack Scenario | Naked Vercel Pro | Cloudflare Pro Proxy + WAF | Mitigation Outcome |
|---|---|---|---|
| Scraper Army (50M Requests, 2TB) | $320.00 overage invoice | $0.00 (Blocked by Cloudflare Bot Mgmt) | 100% Bill Protection |
| L7 HTTP Flood (100k Req/sec for 1 hr) | $2,450.00 function execution fee | $0.00 (Absorbed by Cloudflare Anycast) | Site stays online, zero fee |
| Normal Traffic (1TB Bandwidth) | $20 / month base fee | $20 (Vercel) + $25 (Cloudflare Pro) | Predictable $45/mo flat cost |
# Cloudflare WAF Custom Rule: Block Known Aggressive AI Crawlers
(cf.threat_score gt 15) or
(http.user_agent contains "Bytespider") or
(http.user_agent contains "ClaudeBot") or
(http.user_agent contains "GPTBot" and not http.request.uri.path contains "/robots.txt") or
(http.user_agent contains "CCBot")
Action: Block
Configuring Cloudflare Bot Fight Mode or Super Bot Fight Mode (Pro plan) provides enterprise-grade mitigation against distributed botnets. Cloudflare analyzes behavioral client telemetry, browser canvas fingerprints, and TLS cipher suites to classify traffic. Rogue headless crawlers and scrapers attempting to dump your entire site are issued automated JavaScript challenges or dropped instantly, shielding your Vercel edge middleware from absorbing millions of billable invocations.
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Ensure traffic came through Cloudflare proxy, blocking direct IP bypass
const customSecret = request.headers.get('x-cloudflare-custom-secret');
if (process.env.NODE_ENV === 'production' && customSecret !== process.env.CLOUDFLARE_PROXY_SECRET) {
return new NextResponse('Access Denied: Traffic must originate from Cloudflare edge proxy', { status: 403 });
}
return NextResponse.next();
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};
Edge Cache-Control Hardening: Configure public cache headers (`s-maxage=3600, stale-while-revalidate=86400`) on all informational marketing and documentation routes, allowing Cloudflare global CDN edge caches to absorb 99%+ of inbound requests.