Choosing Between Vercel Edge Middleware and Serverless Functions for Request Routing
Decide when to use Vercel Edge Middleware versus a Serverless Function for redirects, rewrites, and header changes based on latency, runtime limits, and need for async I/O.
02 Oct 2025, 05:27 UTC

Decision: Edge Middleware or Serverless Function for routing
When you need to redirect, rewrite, or modify HTTP headers on Vercel, you can choose between Edge Middleware and a Serverless Function. The choice hinges on latency requirements, runtime capabilities, and whether you need access to secrets or external services.
Constraints
- Must run globally with minimal latency for pure routing logic.
- May need to read environment variables, call a database, or perform asynchronous I/O.
- Payload size and execution time limits differ between the two options.
Comparison of supported options
| Feature | Edge Middleware | Serverless Function |
|---|---|---|
| Typical latency | <10 ms (edge, no cold start) |
50‑200 ms (includes possible cold start) |
| Runtime | Node.js 18 with limited Edge APIs (no fs, net, http) |
Node.js 18 with full Node.js standard library |
| Limits | 1 MB payload, 50 ms CPU time per request | 10 s max duration, 1 GB memory |
| When to use | Simple path‑based redirects, rewrites, header changes, bot authentication, A/B testing | API endpoints, database access, file uploads, webhooks, any logic needing env vars or async I/O |
Trade‑offs
Edge Middleware gives you sub‑10 ms response times and runs at Vercel’s global edge without cold‑start penalties, but it cannot perform asynchronous operations such as database queries or external API calls; any attempt will throw a runtime error. Serverless Functions provide the full Node.js environment, letting you read process.env, connect to a PostgreSQL instance, or call third‑party APIs, yet they incur higher latency and are subject to cold‑start delays, which can affect user‑perceived performance for pure routing tasks.
Concrete implementation: redirect with Edge Middleware
- Open your Vercel project (e.g.,
my-site) in a terminal. - Create
middleware.tsat the repository root:
import { NextResponse } from 'next/server'
export function middleware(req) {
if (req.nextUrl.pathname.startsWith('/old')) {
const url = req.nextUrl.clone()
url.pathname = '/new' + req.nextUrl.pathname.slice(4)
return NextResponse.redirect(url)
}
}
- Tell Vercel to use this file as middleware by adding (or updating)
vercel.jsonat the project root:
{
"middleware": "middleware.ts"
}
- Deploy the change to a preview environment:
vercel --prod # run from the project directory; requires Vercel CLI and permission to push to the linked account
After the deployment finishes, verify the redirect:
- Locally (optional): run
vercel devto start the dev server, then execute:
curl -i http://localhost:3000/old/test
You should see a response header:
HTTP/1.1 302 Found
location: /new/test
- Against the live preview URL (replace
<preview‑url>with the domain shown in the Vercel dashboard):
curl -i https://<preview-url>.vercel.app/old/test
Check that the status is 302 and the location header points to /new/test. In the Vercel dashboard, open the "Edge Middleware" logs for the deployment to confirm the function executed at the edge.
Limitations and practical checks
- Edge Middleware cannot perform asynchronous I/O; if you try
fetchor a database query inside the middleware, the request will fail with a runtime error. - Payload is limited to 1 MB; large request bodies will be rejected before the middleware runs.
- CPU time is capped at 50 ms; heavy computation will be throttled.
To ensure your middleware stays within limits, you can:
- Run
vercel buildlocally and inspect the output size of the middleware bundle. - Use a tool like
webpack-bundle-analyzerto verify the bundle stays well under 1 MB. - Measure execution time with
console.timeinside the middleware during local testing; ensure it stays far below 50 ms.
Rollback considerations
Changing the middleware file or vercel.json creates a new deployment. If you discover an issue after promoting to production, you can revert to a previous deployment from the Vercel dashboard’s "Deployments" tab; this does not require any additional code changes and restores the prior routing behavior instantly.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.