Skip to content
Back to Deployment

Rate Limiting at the Edge

Protect APIs from abuse with edge-based rate limiting using token buckets or sliding windows.

EdgeAdvanced

Why

Edge rate limiting blocks abuse before it reaches your origin, saving compute and database costs. Cloudflare's edge network spans 330+ cities with sub-50ms p95 latency globally.

Edge functions reduce TTFB by 60-80% compared to origin servers, and Akamai reports 40% of enterprises now use edge compute in 2024.

When

Public APIs, login endpoints, or any resource susceptible to brute force/scraping. Avoid edge functions for stateful logic requiring database writes — edge runtimes have no persistent connection pool.

Skip if you need long-running tasks (>30s) or heavy CPU computation.

How

# Vercel Edge Config + rate limiting import { get } from '@vercel/edge-config'; export default async function handler(req: Request) { const ip = req.headers.get('x-forwarded-for') || 'unknown'; const key = `ratelimit:${ip}`; const count = parseInt(await get(key) || '0'); if (count >= 100) { return new Response('Too Many Requests', { status: 429, headers: { 'Retry-After': '60' } }); } // Increment counter (use Upstash Redis for atomic) await fetch(`https://api.upstash.com/redis/incr/${key}`); return handler(req); } 4. Verify deployment — curl -I https://your-app.example.com 5. Monitor logs — check for errors in first 5 minutes 6. Rollback if needed — revert to previous version

Example

# Cloudflare Workers rate limiting export default { async fetch(req, env) { const ip = req.headers.get('cf-connecting-ip'); const { pathname } = new URL(req.url); const rule = { pathname: '/api/*', limit: 100, period: 60, }; const count = await env.RATE_LIMIT.get(ip) || 0; if (count >= rule.limit) { return new Response('Rate limited', { status: 429 }); } return fetch(req); } };

Common Problems

  • ⚠Rate limit too strict — tune based on legitimate traffic patterns
  • ⚠Distributed requests bypass limit — use IP + user ID composite key
  • ⚠Configuration drift between environments — use infrastructure-as-code (Terraform/Pulumi) to keep dev/staging/prod identical

Best Practices

  • ✓Use 429 with Retry-After — clients can retry gracefully
  • ✓Use sliding window — smoother than fixed window
  • ✓Set up health checks and graceful shutdown — handle SIGTERM to drain in-flight requests before exit

FAQ