cyh-lab.com, chart.cyh-lab.com, baby.cyh-lab.com 세 사이트를 모두 Vercel 무료 플랜(Hobby)으로 운영하고 있다. 무료라서 한계가 있겠지 싶었는데, 개인 프로젝트 수준에서는 생각보다 괜찮다. 다만 몇 가지 제한에 걸려서 설정을 바꾼 부분이 있어서 정리해둔다.
Vercel Hobby 플랜의 주요 제한
자세한 수치는 공식 문서가 맞지만, 실제로 운영하면서 체감한 제한은 크게 세 가지였다.
Serverless Function 실행 시간. 무료 플랜은 Function 실행 시간이 10초로 제한된다. 외부 API 응답이 느리거나 처리 로직이 복잡하면 timeout이 난다. chart.cyh-lab.com에서 주식 데이터를 받아와서 가공하는 Route Handler가 처음에 간헐적으로 timeout이 났는데, API 호출 최적화로 해결했다.
빌드 시간. 월 빌드 시간 제한이 있다. 세 프로젝트를 자주 배포하면 소진될 수 있다. 아직 한도에 걸린 적은 없지만, 불필요한 배포는 줄이려고 의식하고 있다.
팀 기능 없음. 혼자 운영하는 거라 상관없는데, 협업이 필요하면 유료 플랜으로 가야 한다.
여러 프로젝트를 한 계정에서 관리하는 법
세 레포를 각각 Vercel 프로젝트로 연결해두면 GitHub에 push할 때마다 자동으로 배포가 된다. 대시보드에서 프로젝트별로 배포 상태, 로그, 환경변수를 확인할 수 있다.
주의할 점은 Hobby 플랜은 상업적 이용이 제한된다는 것이다. 개인 프로젝트나 취미 프로젝트 용도로는 괜찮지만, 광고 수익이나 유료 서비스를 운영하려면 Pro 플랜으로 전환해야 한다는 게 약관 내용이다. 규모가 커지면 이 부분을 고려해야 한다.
배포 불필요한 브랜치 푸시는 무시하게 설정
기본적으로 모든 브랜치에 push하면 Preview 배포가 생성된다. 실험적인 브랜치를 자주 만들면 빌드 시간이 빨리 소진될 수 있다.
vercel.json에서 특정 브랜치만 자동 배포하도록 설정할 수 있다.
{
"git": {
"deploymentEnabled": {
"main": true,
"develop": false
}
}
}이렇게 하면 main에 push할 때만 배포되고, develop이나 다른 브랜치는 수동으로 배포해야 한다. 빌드 시간 관리에 도움이 된다.
Function 실행 시간 timeout 해결한 방법
앞서 말한 Route Handler timeout 문제는 두 가지 방법으로 해결했다.
첫 번째는 불필요한 데이터 가공을 클라이언트로 옮긴 것이다. 서버에서 무거운 계산을 하지 않고, 원본 데이터만 내려줘서 Function 실행 시간을 줄였다.
두 번째는 외부 API 호출에 timeout을 직접 설정한 것이다.
// app/api/stock/route.ts
export async function GET(request: Request) {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 8000) // 8초 timeout
try {
const res = await fetch('https://api.example.com/stock', {
signal: controller.signal,
})
clearTimeout(timeoutId)
const data = await res.json()
return Response.json(data)
} catch (e) {
clearTimeout(timeoutId)
return Response.json({ error: 'timeout' }, { status: 504 })
}
}Vercel 10초 제한보다 짧은 8초로 abort를 걸어서, 외부 API가 느릴 때 깔끔하게 에러 응답을 내려주도록 했다.
지금 시점 기준 결론
개인 프로젝트 세 개를 무료로 안정적으로 운영하고 있다. 트래픽이 적은 초반에는 Hobby 플랜으로 충분하다. 다만 상업적 수익이 생기거나 트래픽이 늘어나면 Pro 플랜 전환을 고려해야 한다는 걸 인지하고 있다.