Skip to main content
Jodei
Insights

Edge Runtime vs Node.js: Choosing the Right Environment for AI Workloads in Next.js

Edge functions start faster and run closer to users, but lack the Node.js APIs that most AI SDKs require. Here's how to pick the right runtime for each part of your AI-native Next.js app.

6 min read

When you deploy a Next.js app with AI features, every route implicitly chooses a JavaScript runtime: Node.js (the default) or Edge. The choice is invisible until it breaks something — usually when an AI SDK call fails in production because the Edge runtime doesn't support a Node.js built-in the SDK depends on.

This post lays out what each runtime actually gives you, which AI workloads fit each one, and how to make the decision deliberately instead of discovering it from an error log.

What the Edge runtime is — and what it lacks

The Edge runtime is a stripped-down JavaScript environment built on the Web Platform APIs (fetch, Request, Response, ReadableStream, crypto). It runs on Cloudflare Workers, Vercel Edge Functions, or similar platforms that execute code close to the user in distributed data centers.

The upside is startup time. An Edge function has no cold start worth measuring — it's typically under 5 ms because there is no full Node.js process to spin up. For latency-sensitive routes that run before every page render, that matters.

The downside is the missing surface area. Edge does not have:

  • fs, path, os, or any Node.js core module
  • Native add-ons (.node binaries)
  • process.env outside of predeclared variables (platform-dependent)
  • Long-running connections or persistent in-memory state between requests

This rules out a surprising number of AI dependencies. Many SDKs use node:buffer, node:stream, or node:crypto under the hood, even when their public API looks web-friendly. Check package.json → exports for an edge condition before assuming compatibility.

What Node.js gives you

The Node.js runtime in Next.js 16 is the full server environment. You get the complete standard library, native binary support, long-lived connections, and no restrictions on which npm packages you can import.

The tradeoff is cold start. On serverless platforms, a Node.js function can take 200–800 ms to initialize when the container is cold. For most AI routes this is fine — the LLM call itself takes 500 ms to several seconds, so a one-time 400 ms initialization cost is invisible inside a warm connection.

Where cold start matters most is in middleware, which runs before every request. A slow middleware cold start applies a tax to your entire site, not just AI routes.

The decision by workload type

Middleware (auth, redirects, geolocation): Edge

Middleware in Next.js runs in the Edge runtime by default, and that default is correct. It executes on every request before the response is served, so startup latency is the dominant factor. Keep middleware small — validate a JWT using the Web Crypto API, read a cookie, decide which locale to serve — and leave AI inference elsewhere.

Streaming LLM responses: Node.js

If you are using the Vercel AI SDK's streamText or streamObject, use Node.js. The SDK's streaming helpers rely on node:stream internally, and even the edge-compatible paths are tested more thoroughly on Node.js. In Next.js 16, a Route Handler defaults to Node.js unless you export runtime = "edge" — so the default is already right.

// src/app/api/generate/route.ts — Node.js (default, no export needed)
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";

export async function POST(request: Request) {
  const { prompt } = await request.json();
  const result = await streamText({
    model: openai("gpt-4o-mini"),
    prompt,
  });
  return result.toDataStreamResponse();
}

Embedding generation and vector search: Node.js

Embedding pipelines often involve chunking text with Buffer, calling an embeddings endpoint, and writing results to a vector database client that uses TCP connections. All of this requires Node.js. The batch sizes also tend to be large enough that cold start is irrelevant — the compute cost dominates.

Personalization headers and A/B bucketing: Edge

If you want to return different AI-generated content variants to different users, Edge middleware is the right place to set the routing cookie or header. The AI generation itself still happens on Node.js — Edge just decides which variant to serve before the page renders, without adding a full Node.js startup to every request.

Background and deferred work: Node.js via after()

Next.js 16's after() API lets you run callbacks after the response is sent. This is strictly a Node.js feature — Edge functions terminate as soon as the response closes. Use after() on Node.js Route Handlers for token logging, usage audit trails, and async embedding pipelines that should not block the streamed response.

// Node.js only — after() is not available in the Edge runtime
import { after } from "next/server";

export async function POST(request: Request) {
  const result = await streamText({ ... });

  after(async () => {
    await logTokenUsage(result.usage);
  });

  return result.toDataStreamResponse();
}

Declaring your runtime in Next.js 16

You opt into Edge per route by exporting a runtime constant. Omitting it defaults to Node.js everywhere except middleware.

// opt a single Route Handler into Edge
export const runtime = "edge";

// or lock it to Node.js explicitly (rarely needed, but documents intent)
export const runtime = "nodejs";

If you set runtime = "edge"and the route imports a Node.js-only package, the build will fail with a clear error listing the unsupported import. That failure at build time is a feature — it's better than a silent runtime error in production.

A practical default policy

For AI-native apps on Next.js 16, the simplest policy that causes the fewest surprises:

  • Middleware → Edge (it's the default and the right call)
  • All Route Handlers that touch an AI SDK → Node.js (the default; do nothing)
  • Server Components that call fetch-only AI APIs → fine on Edge if you need the startup advantage, but only after verifying the SDK has an edge export

The short version: leave everything at the default, move middleware logic to Edge-compatible Web APIs, and only opt a route into Edge when you have measured a cold-start problem worth solving. Most AI workloads never hit that bar.