Vercel Edge Runtime과 Node.js Runtime 차이
Vercel Edge Runtime과 Node.js Runtime의 차이점, 사용 사례, 성능 특성을 비교 분석합니다.
Vercel Edge Runtime과 Node.js Runtime 차이
Introduction
Vercel은 두 가지 주요 런타임을 제공합니다: Edge Runtime과 Node.js Runtime. 각각의 런타임은 다른 특성과 사용 사례를 가지고 있으며, 적절한 선택은 애플리케이션 성능에 큰 영향을 미칩니다. 이 글에서는 두 런타임의 차이점을 깊이 분석하고, 어떤 상황에서 어떤 런타임을 선택해야 하는지 알아보겠습니다.
Environment
- Vercel 프로젝트 (Next.js 14+)
- Edge Runtime: V8 엔진 기반
- Node.js Runtime: Node.js 18+
- 글로벌 CDN: Vercel Edge Network
Problem
어떤 런타임을 선택해야 할지 혼란스러운 상황이 많습니다:
// 같은 API 엔드포인트에서 다른 런타임 사용 시 발생하는 문제
Error: Module not found: Can't resolve 'fs'
Error: Module not found: Can't resolve 'path'
Error: Node.js APIs are not available in Edge RuntimeAnalysis
Edge Runtime
Edge Runtime은 V8 엔진 기반의 경량 런타임으로, 전 세계 Vercel Edge 노드에서 실행됩니다.
특징:
- Cold start 시간: ~5ms
- 실행 시간 제한: 30초 (Hobby), 300초 (Pro)
- 글로벌 배포: 모든 Edge 노드에서 실행
- 제한된 Node.js API 지원
- Web API 표준 준수
지원하는 기능:
// 지원되는 기능
fetch() // HTTP 요청
Response/Request // Web API
URL/URLPattern // URL 처리
crypto // 암호화
TextEncoder/Decoder // 텍스트 처리
// 지원되지 않는 기능
fs // 파일 시스템
path // 경로 처리
child_process // 프로세스 관리
require() // CommonJS 모듈Node.js Runtime
Node.js Runtime은 전통적인 Node.js 환경에서 실행됩니다.
특징:
- Cold start 시간: ~250ms
- 실행 시간 제한: 10초 (Hobby), 60초 (Pro)
- 특정 리전에서 실행
- 전체 Node.js API 지원
- npm 패키지 호환성
지원하는 기능:
// 모든 Node.js API 지원
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const { createHash } = require('crypto');
// npm 패키지 사용 가능
const { PrismaClient } = require('@prisma/client');
const redis = require('redis');Solution
1. 런타임 선택 기준
// Edge Runtime이 적합한 경우
export const runtime = 'edge';
// 데이터베이스 연결이 필요한 경우
// Node.js Runtime이 적합
export const runtime = 'nodejs';
// 미들웨어에서의 사용
export const config = {
runtime: 'edge'
};2. Edge Runtime 사용 예시
// app/api/edge-endpoint/route.js
export const runtime = 'edge';
export async function GET(request) {
const { searchParams } = new URL(request.url);
const query = searchParams.get('q');
// 외부 API 호출
const response = await fetch(`https://api.example.com/search?q=${query}`);
const data = await response.json();
return Response.json(data);
}3. Node.js Runtime 사용 예시
// app/api/data-endpoint/route.js
export const runtime = 'nodejs';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export async function GET(request) {
const users = await prisma.user.findMany({
take: 10,
orderBy: { createdAt: 'desc' }
});
return Response.json(users);
}4. 하이브리드 접근법
// lib/optimized-fetch.js
export async function optimizedFetch(url, options = {}) {
// Edge Runtime에서 실행되는 유틸리티 함수
const controller = new AbortController();
const timeout = options.timeout || 5000;
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(timeoutId);
return response;
} catch (error) {
clearTimeout(timeoutId);
throw error;
}
}5. 미들웨어에서의 런타임 선택
// middleware.js
import { NextResponse } from 'next/server';
export const config = {
matcher: ['/api/:path*']
};
export function middleware(request) {
const origin = request.headers.get('origin');
// CORS 처리
const response = NextResponse.next();
response.headers.set('Access-Control-Allow-Origin', origin);
response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
return response;
}6. 성능 비교 테스트
// scripts/benchmark-runtimes.js
async function testEdgeRuntime() {
const start = Date.now();
const response = await fetch('https://your-app.vercel.app/api/edge-test');
await response.json();
return Date.now() - start;
}
async function testNodeRuntime() {
const start = Date.now();
const response = await fetch('https://your-app.vercel.app/api/node-test');
await response.json();
return Date.now() - start;
}
// 벤치마크 실행
async function runBenchmark() {
const iterations = 10;
const edgeTimes = [];
const nodeTimes = [];
for (let i = 0; i < iterations; i++) {
edgeTimes.push(await testEdgeRuntime());
nodeTimes.push(await testNodeRuntime());
}
const edgeAvg = edgeTimes.reduce((a, b) => a + b) / iterations;
const nodeAvg = nodeTimes.reduce((a, b) => a + b) / iterations;
console.log(`Edge Runtime Average: ${edgeAvg}ms`);
console.log(`Node.js Runtime Average: ${nodeAvg}ms`);
}Lessons Learned
- Cold Start 시간: Edge Runtime은 훨씬 빠른 cold start를 제공합니다.
- API 제한: Edge Runtime은 제한된 API만 지원하므로, 사용 전 호환성을 확인해야 합니다.
- 글로벌 배포: Edge Runtime은 전 세계에서 실행되어 더 빠른 응답 시간을 제공합니다.
- 메모리 제한: Edge Runtime은 메모리 제한이 더 엄격합니다.
- 데이터베이스 연결: 데이터베이스 연결이 필요한 경우 Node.js Runtime을 선택해야 합니다.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.