Vercel Services: 풀스택 배포 단위는 이제 “서비스 그래프”다
대부분의 제품은 사용자에게 하나의 앱으로 보인다. 하지만 내부는 Next.js 프론트엔드, Python API, Go worker, Hono edge service, 별도 cron, 별도 queue처럼 흩어져 있다. 문제는 코드가 나뉘는 것이 아니다. 배포, 프리뷰, 롤백, 로그, 내부 호출 경계가 서로 다른 시스템에 흩어질 때 팀의 운영 판단이 느려진다는 점이다.
무슨 일이 있었나
Vercel은 2026년 6월 30일 Vercel Services를 발표했다. 공식 changelog와 블로그에 따르면 이제 하나의 Vercel Project 안에서 여러 프론트엔드와 백엔드를 함께 배포할 수 있고, 서비스들은 공유 도메인 위에서 routing, build, preview, rollback을 함께 다룬다.
구성의 중심은 vercel.json의 services 키다. 각 service는 root, framework, entrypoint, runtime, bindings 같은 속성으로 정의된다. public traffic은 top-level rewrite가 service로 라우팅할 때만 들어가고, rewrite가 없는 service는 인터넷에서 직접 접근되지 않는다.
또 하나 중요한 변화는 service binding이다. binding은 한 service의 server-side code가 다른 service를 public internet에 노출하지 않고 호출하도록 URL을 주입한다. 공식 문서는 binding이 접근 권한과 URL 생성을 함께 처리하며, preview deployment에서도 같은 preview 안의 target service를 가리킨다고 설명한다.
왜 개발팀에 중요한가
Vercel Services는 “Vercel에서 백엔드도 돌릴 수 있다”는 단순한 주장보다 더 큰 구조 변화다. 지금까지 많은 팀은 프론트엔드는 Vercel, API는 Fly.io나 Render, worker는 별도 VM, cron은 GitHub Actions처럼 쪼개서 운영했다. 이 방식은 유연하지만, preview 환경과 rollback 단위가 갈라질 때 실제 제품 변경의 원자성이 깨진다.
Services 모델은 배포 단위를 repository나 framework가 아니라 service graph로 다시 정의한다. 프론트엔드와 백엔드가 같이 빌드되고, 같은 preview deployment에 올라가고, 같은 rollback 판단 안에 들어오면 “이 UI 변경이 이 API 변경과 같이 검증됐는가”를 더 명확히 답할 수 있다.
그 대신 vercel.json은 더 이상 배포 보조 설정이 아니다. 어떤 service가 public entry point인지, 어떤 service가 내부 binding으로만 호출되는지, 어떤 root가 어떤 runtime으로 빌드되는지가 운영 계약이 된다. 코드 리뷰에서 application code만 볼 것이 아니라 services, rewrites, bindings diff를 함께 봐야 한다.
커뮤니티 신호
Next.js 커뮤니티에서는 오래전부터 “별도 백엔드를 둘 것인가, Vercel Functions를 백엔드로 쓸 것인가”라는 논쟁이 반복됐다. Reddit의 관련 토론에는 timeout, cold start, database pooling, WebSocket, cron 같은 고민이 등장한다. 이 글은 그런 커뮤니티 글을 사실 출처로 쓰지는 않지만, 개발자들이 실제로 어디에서 friction을 느끼는지 보여주는 신호로 본다.
반대편 신호도 있다. Hacker News의 Vercel 보안 사고 논의처럼, 플랫폼 하나에 많은 배포와 secret, CI, 개발 도구가 집중될 때 생기는 신뢰 집중을 우려하는 목소리도 있다. Services는 운영 표면을 단순화하지만, 동시에 더 많은 app boundary를 하나의 platform control plane에 모을 수 있다.
따라서 실무자의 질문은 “Vercel Services를 써야 하나 말아야 하나”가 아니라 “어떤 service boundary를 한 deployment로 묶으면 이득이고, 어떤 boundary는 별도 플랫폼·별도 blast radius로 남겨야 하는가”여야 한다.
개발·운영 영향
첫 번째 영향은 preview의 의미다. frontend와 backend가 같은 preview deployment 안에 있으면 API 계약 변경, UI 변경, worker 변경을 한 링크에서 검증할 수 있다. 반대로 service가 많아질수록 preview 데이터, migration, seed, external dependency를 어떻게 맞출지 더 엄격히 정해야 한다.
두 번째 영향은 routing ownership이다. Services routing 문서는 top-level rewrite가 public traffic의 소유자라고 설명한다. 요청은 첫 번째로 매칭된 service로 최종 라우팅되고, service 내부에서 route가 없다고 해서 다른 top-level rewrite로 자동 fallback하지 않는다. 이는 /api/(.*)와 /(.*) 같은 규칙 순서가 운영 사고로 이어질 수 있음을 뜻한다.
세 번째 영향은 private communication이다. binding은 public route 없이 service 간 호출을 가능하게 하지만 인증 자체를 대신하지 않는다. 공식 문서도 application-level authorization이 필요하면 service code에서 처리하라고 명시한다. 즉 internal URL이 있다고 해서 trust boundary가 사라지는 것은 아니다.
네 번째 영향은 비용 관찰이다. Services pricing 문서는 service-to-service call을 service request로 계산하고, public internet request와 별도로 다룬다. 팀은 “한 요청이 내부에서 몇 개 service call로 증폭되는가”를 로그와 비용 모델에 넣어야 한다.
다섯 번째 영향은 로컬 개발이다. docs에 따르면 vercel dev는 모든 service를 함께 실행하고 binding environment variable도 주입한다. 이것은 production-like local 환경에 가깝지만, service startup time과 local dependency orchestration이 새 병목이 될 수 있다.
지금 적용할 체크리스트
1. 먼저 service boundary를 코드 폴더가 아니라 배포 실패 단위로 나눈다. 같이 rollback해야 하면 같은 service graph에 넣고, blast radius를 분리해야 하면 별도 project나 플랫폼을 검토한다.
2. 모든 public ingress를 top-level rewrites에서 리뷰한다. catch-all rule은 마지막에 두고, /api/(.*) 같은 규칙이 어떤 service로 들어가는지 테스트한다.
3. 내부 호출은 hardcoded hostname 대신 bindings로 선언한다. 다만 binding은 network reachability일 뿐 application authorization이 아니므로 service 간 인증·서명을 별도로 설계한다.
4. PR 템플릿에 services, rewrites, bindings, runtime, entrypoint 변경 여부를 넣는다. application diff와 platform diff를 같은 review에서 본다.
5. preview 환경의 데이터 전략을 정한다. UI와 API가 같이 preview되더라도 migration, seed data, external API token이 맞지 않으면 검증 신뢰도가 낮다.
6. service-to-service call 수를 관측한다. 사용자 요청 하나가 내부 call을 여러 번 만들면 latency와 비용이 함께 증가한다.
7. beta 기능으로 다룬다. 공식 docs가 Services를 beta로 표시하므로, 핵심 production workload를 옮기기 전 route fallback, binding, logs, rollback, local dev를 별도 리허설한다.
리스크와 반론
첫 번째 리스크는 platform concentration이다. 한 project 안에 frontend, backend, worker, internal service를 모으면 운영은 편해지지만 platform outage, account 권한, secret policy가 더 중요한 단일 통제면이 된다. 민감한 시스템은 별도 계정·별도 project·별도 cloud에 남겨야 할 수 있다.
두 번째 리스크는 network boundary 오해다. binding은 public exposure를 줄이는 좋은 기본값이지만 인증을 자동으로 해결하지 않는다. 내부 service라도 tenant, role, job source, replay 방지를 검증해야 한다.
세 번째 리스크는 비용 착시다. active CPU와 service request 단위는 워크로드에 따라 유리할 수도 불리할 수도 있다. 특히 내부 fan-out이 많은 API, long-running worker, WebSocket, container runtime은 실제 사용 패턴으로 계산해야 한다.
반론도 유효하다. 이미 Kubernetes, Fly Machines, Cloud Run, ECS로 안정적인 multi-service 운영을 하고 있다면 Services가 반드시 더 낫지 않다. 이 기능의 강점은 “모든 백엔드의 종착지”가 아니라 Vercel preview, domain, deployment workflow 안에서 풀스택 변경을 작게 운영하고 싶은 팀에 있다.
Vercel Services 도입 전 점검표
• 1. 먼저 service boundary를 코드 폴더가 아니라 배포 실패 단위로 나눈다. 같이 rollback해야 하면 같은 service graph에 넣고, blast radius를 분리해야 하면 별도 project나 플랫폼을 검토한다.
정리
Vercel Services는 “프론트엔드 플랫폼이 백엔드도 지원한다”는 뉴스가 아니다. vercel.json을 서비스 그래프의 운영 계약으로 바꾸는 업데이트다. 도입 전 팀이 봐야 할 것은 framework 지원 목록보다 public rewrite, internal binding, rollback 단위, 비용 fan-out, 권한 모델이다. 잘 쓰면 preview와 rollback이 더 선명해지고, 대충 쓰면 하나의 설정 파일에 너무 많은 운영 책임이 숨어든다.
출처
- Vercel Changelog: Run multiple frameworks in one project with Vercel Services
- Vercel Blog: Vercel Services - Run full stack on Vercel
- Vercel Docs: Services overview
- Vercel Docs: Services routing
- Vercel Docs: Service bindings
- Vercel Docs: Services pricing and limits
- Reddit discussion: separate backend server vs Vercel functions
- Hacker News discussion: platform trust and Vercel security incident