Choosing Between Node.js and Edge Runtimes for Vercel API Routes
Guide to picking Node.js or Edge runtime for Vercel Next.js API routes, covering constraints, a comparison table, trade‑offs, example code and validation steps.
05 Oct 2026, 10:51 UTC

Decision: select the runtime for a Vercel-hosted Next.js API route
When you add an API route in a Next.js app deployed on Vercel you must decide whether the handler runs in the Node.js runtime or the Edge runtime. The decision influences library compatibility, latency, cold‑start behavior, bundle size and cost. The constraints you typically weigh are:
- Need for Node‑only APIs (fs, child_process, net, native addons or specific database drivers)
- Target p99 latency for a globally distributed audience
- Acceptable cold‑start penalty
- Bundle‑size limits imposed by your Vercel plan
- Cost per GB‑hour of function execution
Option comparison
| Option | Cold start | API surface | Runs in | Best for |
|---|---|---|---|---|
| Node.js function (default) | Higher (typically tens‑to‑hundreds of ms) | Full Node.js + npm ecosystem | Vercel Function regions (fewer locations) | Database drivers, native dependencies, long‑running jobs |
| Edge function | Lower (often single‑digit ms) | Web APIs only (no fs, child_process, net server) | Many Edge PoPs worldwide | Authentication, redirects, geo‑based responses, lightweight JSON |
| Hybrid: Edge middleware + Node route | Mixed (Edge gate low latency, Node origin higher) | Both runtimes | Edge PoP then Node origin | Global gating/auth before heavy origin work |
Trade‑offs
- Edge gives you lower cold starts and execution closer to the user, but you cannot use Node built‑ins such as
fs,child_processornet, and many npm packages that rely on those APIs fail to bundle. Bundle size is also more tightly constrained. - Node.js supports the full npm ecosystem and long‑lived TCP connections (useful for database connection pooling), but it starts in fewer regions so distant users see higher latency and you pay more for the longer startup time.
- The hybrid pattern lets you keep the Edge advantage for request inspection (e.g., JWT validation) while delegating heavy work to a Node route, at the cost of an extra hop and the need to maintain two separate handlers.
Concrete implementation
To force a route to the Edge runtime add the runtime export. Omit it or set 'nodejs' for the Node.js runtime.
Edge‑only handler (App Router)
// app/api/hello/route.js
export const runtime = 'edge';
export async function GET(request) {
const auth = request.headers.get('authorization');
if (!auth) {
return new Response('Unauthorized', { status: 401 });
}
// Example: lightweight JWT validation using only Web Crypto (available in Edge)
// const payload = await jwtVerify(auth, secret);
return Response.json({ ok: true, msg: 'hello from edge' });
}
Node.js‑only handler (App Router)
// app/api/db/route.js
// No runtime export → defaults to Node.js
import { Client } from 'pg'; // Example Node‑only postgres driver
export async function GET(request) {
const client = new Client({ connectionString: process.env.POSTGRES_URL });
await client.connect();
const res = await client.query('SELECT NOW()');
await client.end();
return Response.json({ time: res.rows[0].now });
}
Validation steps
- Deploy a preview branch (e.g.,
vercel --prodor a preview URL). - In the Vercel dashboard open Runtime Logs for the function invocation; the log line shows the runtime used (
Node.jsorEdge) and the region. - From multiple geographic locations (e.g., using
curlor a service likehttps://check-host.net) measure TTFB and inspect thex-vercel-idheader to confirm the edge PoP for Edge functions. - For Node.js builds, verify that any Node‑only dependency initializes without errors such as
Module not found: fsorReferenceError: self is not definedin the logs. - Run
vercel buildlocally and inspect the output under.vercel/output/functionsto confirm the bundle size and that Edge‑compatible code does not contain forbidden Node built‑ins. - Check the Vercel usage page for invocation count, duration and any warnings about exceeding bundle‑size or execution‑duration limits for your plan.
Limitations and practical checks
- Edge functions cannot open TCP sockets, so connection‑pooling to a traditional database is not possible; you must rely on a serverless‑friendly driver or a proxy.
- Bundle‑size limits differ between Hobby, Pro and Enterprise plans; a library that builds successfully on one plan may be rejected on another.
- Cold‑start measurements vary with traffic spikes, regional capacity and your Vercel plan; treat any single benchmark as indicative, not guaranteed.
- If you use Next.js 15+ App Router caching, confirm that
revalidateorexport const dynamic = 'force-static'does not conflict with your runtime choice.
Decision rule: choose Edge only when every dependency is Web‑API compatible, the work is short and stateless, and you benefit from geographic proximity; choose Node.js whenever you need Node built‑ins, native addons, TCP connection reuse to a database, or longer CPU work; use the hybrid pattern when you want global auth gating at the edge before delegating heavy processing to a Node origin.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.