字节笔记本
2026年7月19日
Next.js Edge Runtime: When and How to Use It
Edge Runtime in Next.js runs your server code on nodes distributed around the world instead of a single region. The tradeoff is that you lose access to Node.js-specific APIs (filesystem, native modules) in exchange for significantly lower latency for users who aren't near your origin server. This post covers when Edge Runtime makes sense and how to set it up.
The Problem It Solves
If your server is in the US and a user in Asia hits a dynamic endpoint, the round-trip alone adds hundreds of milliseconds. Static assets are easy to cache at the edge via CDN, but dynamic routes (authentication, personalization, A/B testing, geolocation) traditionally need to run on your origin server. Edge Runtime lets you run those dynamic routes on edge nodes closer to the user.
Edge Runtime vs Node.js Runtime
| Node.js Runtime | Edge Runtime | |
|---|---|---|
| API access | Full Node.js APIs + npm packages | Web APIs only (fetch, Request, Response, etc.) |
| Startup time | Slower cold starts | Very fast |
| Execution | Single region (or multi-region with extra config) | Runs on edge nodes globally |
| Filesystem | Yes | No |
| Native modules | Yes | No |
| Best for | Heavy computation, database writes, file processing | Auth, redirects, geolocation, lightweight dynamic content |
Enabling Edge Runtime
Add the runtime export to your page, layout, or route handler:
// app/page.js
export const runtime = 'edge'
export default function Page() {
return <h1>This runs on an edge node</h1>
}That's it for basic setup. Next.js handles deployment automatically on Vercel.
Practical Example: Geolocation-Based Pricing
// app/api/price/route.js
export const runtime = 'edge'
export async function GET(request) {
const { geo } = request
const country = geo?.country || 'US'
const prices = {
US: { currency: 'USD', symbol: '$', rate: 1 },
EU: { currency: 'EUR', symbol: '€', rate: 0.92 },
JP: { currency: 'JPY', symbol: '¥', rate: 150 },
}
const pricing = prices[country] || prices.US
return Response.json({ pricing, country })
}The request.geo object is only available on Edge Runtime — it's populated based on the edge node's location.
Practical Example: Locale Detection Middleware
// middleware.js
export const config = {
runtime: 'edge',
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}
export function middleware(request) {
const acceptLanguage = request.headers.get('accept-language') || ''
const locale = acceptLanguage.startsWith('zh') ? 'zh' : 'en'
const url = request.nextUrl.clone()
url.pathname = `/${locale}${url.pathname}`
return Response.redirect(url)
}Middleware runs on Edge Runtime by default in Next.js, so you don't need to explicitly declare it — but it's worth knowing that's what's happening.
When Edge Runtime Is Worth It
Good fit:
- Authentication checks and redirects
- A/B testing and feature flags
- Geolocation (country, city, region)
- Personalized content based on headers
- Lightweight API responses
Not a good fit:
- Heavy data processing
- Image manipulation
- Database migrations or bulk operations
- Anything that needs native Node.js modules
Limitations to Keep in Mind
- Execution time caps — typically 30 seconds on Vercel. If your handler needs longer, use Node.js runtime.
- No filesystem — you can't read/write files. Use external storage (S3, R2, databases) instead.
- Package compatibility — some npm packages rely on Node.js internals and won't work. Always test.
- Database connections — some database drivers use Node.js APIs. Use edge-compatible clients (like Prisma with the edge adapter, or HTTP-based databases like Supabase).