AI가 짠 7,000만 개의 웹앱을 128MB Isolate에서 SSR로 서빙하는 법: TanStack Start와 Cloudflare Dynamic Workers 해부
Cloudflare Connect 2026에서 공개된 Lovable의 7,000만 개 AI 생성 웹앱 서빙 아키텍처(TanStack Start SSR 및 Cloudflare Dynamic Workers)를 정리한다. R2·KV 기반 1초 미만 콜드 스타트 설계와 V8 Isolate 128MB 메모리 한도(OOM) 방지를 위한 서버·클라이언트 번들 분리 원칙을 살펴본다.
Cloudflare Dynamic Workers 및 TanStack Start SSR 기반 대규모 멀티테넌트 앱 서빙 아키텍처 구조도
결론부터 말하면 AI 에이전트가 매주 100만 개씩 찍어내는 수천만 개의 웹 애플리케이션에 서버 사이드 렌더링(SSR)을 제공하려면, 상시 떠 있는 VM이나 컨테이너가 아니라 요청 시점에만 1초 미만으로 깨어나는 V8 Isolate(Dynamic Workers)와 128MB 메모리 예산을 지키는 엄격한 서버·클라이언트 번들 분리가 핵심이다. Cloudflare Connect 2026의 'TanStack Start on Workers: Server-rendering apps an AI just wrote' 세션에서 AI 앱 빌더 플랫폼 Lovable 엔지니어링 팀은 누적 7,000만 개의 애플리케이션(일일 Worker 요청 70억 건)을 호스팅하며 기존 클라이언트 렌더링 SPA와 Next.js 기반 자체 프론트엔드를 TanStack Start 및 **Cloudflare Dynamic Workers(Workers for Platforms)**로 전면 이전한 아키텍처와 실무 시행착오를 공개했다.
단, 영상에서 제시된 R2 콜드 스타트 1초 미만 수치나 일일 70억 건 처리 사례는 Lovable의 자체 프로덕션 인프라 발표치이며 직접 측정한 벤치마크나 사용 후기가 아니므로, 워크로드의 번들 크기와 데이터베이스 연결 구조에 따라 실제 지연 시간은 달라질 수 있다.
1. 7,000만 개의 앱을 어떻게 서빙할 것인가: R2 정적 SPA에서 Dynamic Workers SSR로의 전환
Cloudflare Connect 2026 — TanStack Start on Workers: Server-rendering apps an AI just wrote 공식 세션
초기 AI 코딩 플랫폼들은 생성된 앱을 단순 React SPA(Single Page Application)로 빌드해 Cloudflare R2 객체 스토리지에 올리고 정적 파일만 서빙했다. 이 방식은 인프라 구축이 단순하지만, 빈 <div id="root">만 내려주기 때문에 검색 엔진 최적화(SEO)가 불가능하고 초기 데이터 페칭 워터폴이 발생하며 프론트엔드와 백엔드 서빙 계층이 쪼개지는 한계가 있었다.
반면 7,000만 개의 앱 각각에 상시 실행 중인 서버(VM·컨테이너)를 붙여두는 것은 비용상 불가능하다. 이를 해결하기 위해 도입된 구조가 **Proxy Worker(Dynamic Dispatch Worker)**가 요청 시점에 R2와 KV에서 번들을 읽어 온디맨드로 하위 **Dynamic Worker(workerd V8 Isolate)**를 스폰하는 아키텍처다.
| 비교 항목 | 초기 React SPA + R2 정적 호스팅 | 전통적 컨테이너/VM 기반 SSR 호스팅 | TanStack Start + Cloudflare Dynamic Workers |
| 렌더링 및 SEO 특성 | 클라이언트 JS 실행 전까지 빈 HTML 반환 (SEO 및 초기 체감 속도 취약) | 완전한 서버 사이드 렌더링(SSR) 지원 | 정적 프리렌더링(Prerendering) 경로와 동적 SSR + Dehydration/Hydration 경로를 라우트별로 선택 적용 |
| 격리 단위 및 메모리 오버헤드 | 서버 연산 없음 (브라우저 전담) | 컨테이너/VM 단위 격리 (수백 MB~수 GB 메모리 점유, 유휴 비용 발생) | |
| 콜드 스타트(Cold Start) 경로 | 정적 파일 즉시 반환 | 컨테이너 이미지 풀 및 런타임 부팅에 수 초~수십 초 소요 | 완전 콜드 상태(R2 보관 → KV 캐시 → Dynamic Worker 스폰)에서도 1초 미만(< 1s)에 응답 시작 |
| 시크릿(Secret) 변경 시 반영 | 빌드 타임 주입 시 전체 앱 재빌드·재배포 필요 | 컨테이너 롤링 재시작 필요 | 코드와 시크릿 바인딩을 분리하여, 시크릿 변경 시 기존 Isolate만 즉시 무효화(Invalidate) 후 무중단 재생성 |
요청이 my-app.lovable.app으로 들어오면 앞단의 Proxy Worker가 URL에서 앱 ID를 추출해 코로케이션된 캐시에서 메타데이터(최신 배포 버전, 접근 권한, 정적/동적 라우트 여부)를 조회한다. 정적 라우트라면 동적 워커를 띄우지 않고 즉시 HTML/CSS/JS를 반환하고, SSR이 필요한 라우트일 때만 Dynamic Worker를 스폰해 실행한다.
2. 왜 AI 코드 생성과 도그푸딩에 TanStack Start가 유리한가
세션에서 가장 흥미로운 대목은 Lovable 팀이 원래 Next.js로 구축했던 자사 메인 플랫폼 전체를 들어내고 **TanStack Start**로 재작성해 자신들의 Dynamic Workers 인프라 위에서 직접 호스팅(Dogfooding)하기 시작했다는 점이다.
AI 에이전트가 코드를 읽고 수정할 때 TanStack Start의 동형(Isomorphic) 실행 모델과 서버 함수(createServerFn)는 두 가지 뚜렷한 이점을 제공한다.
- 암묵적 경계 대신 명시적 RPC(
createServerFn) 사용:'use server'지시어처럼 파일이나 함수 위치에 따라 네트워크 경계가 암묵적으로 생기는 방식 대신,createServerFn을 통해 서버 전용 로직과 입력 검증(Zod 등)을 단일 코드베이스 안에서 명시적으로 선언한다.
- 빌드 타임 자동 스텁(Stub) 치환: 서버 번들에서는
createServerFn내부 코드가 환경변수·시크릿에 직접 접근하며 그대로 실행되고, 클라이언트 번들에서는 Vite 빌드 단계가 해당 함수 본문을 제거한 뒤 서버로 HTTP 요청을 보내는 얇은 RPC 스텁(Request Stub)으로 자동 치환한다.
3. 실전 스케일링 교훈: 128MB 메모리 벽(OOM)과 콜드 스타트 다이어트
자사 메인 서비스를 동일한 Worker 스택으로 이전(Dogfooding)하면서 팀이 가장 먼저 부딪힌 실무 장애는 **Cloudflare Worker Isolate의 128MB 메모리 제한으로 인한 OOM(Out Of Memory)**이었다.
| 병목 구간 | 실제 발생한 장애 원인 | 해결 아키텍처 및 에이전트 가드레일 |
| Isolate 128MB 메모리 초과 (OOM) | 단일 Isolate(128MB) 안에서 서버 번들 코드 자체의 크기 + 동시 처리 중인 요청들의 힙 메모리가 예산을 공유함. 마이그레이션 초기 실수로 무거운 TypeScript 컴파일러와 구문 강조기(Syntax Highlighter)가 서버 번들에 딸려 들어가면서 즉각 OOM 발생 | 무거운 파서·에디터·하이라이터 의존성은 철저히 클라이언트 전용 번들( createClientOnlyFn / 동적 import)로 격리하고, 이 번들 분리 규칙을 AI 코딩 에이전트의 지침에 내재화하여 주당 100만 개 생성 앱의 OOM을 사전 차단 |
| 콜드 스타트 지연 (Cold Start Latency) | R2에만 있는 콜드 앱을 처음 깨울 때 번들 다운로드·파싱·컴파일 시간이 전체 지연의 대부분을 차지 | 1) 워커 번들을 Cloudflare KV에 캐싱하여 R2 조회 지연 단축 2) 서버 번들 크기 자체를 최소화(Bundle Diet)하여 V8 파싱·컴파일 시간 단축 3) 동적 데이터가 필요 없는 페이지는 TanStack Start의 빌드 타임 Prerendering으로 정적 서빙하여 동적 워커 스폰 자체를 회피 |
| 시크릿 로테이션 시 재배포 비용 | 사용자가 API 키나 DB 비밀번호를 바꿀 때마다 전체 앱 코드를 다시 빌드하고 배포하면 수분 이상 소요 | 앱 코드 번들과 암호화된 시크릿 바인딩을 분리 저장. 시크릿 변경 이벤트 발생 시 코드 재빌드 없이 기존 실행 중인 Isolate만 즉시 무효화(Invalidate)하고 새 시크릿이 주입된 Isolate를 1초 내 스폰 |
이처럼 플랫폼 자신이 가장 큰 테넌트(Largest Tenant)로서 겪은 OOM과 번들 비대화 패턴을 수집해 다시 AI 빌더 에이전트의 프롬프트와 지식 베이스에 피드백 루프(Virtuous Loop)로 주입함으로써, 일반 사용자가 만드는 앱에서도 동일한 메모리 초과 오류가 재발하지 않도록 막는 구조가 핵심이다.
4. 실무 도입 체크리스트
- SSR 서버 번들에 클라이언트 전용 거대 라이브러리 유입 차단: Cloudflare Workers(
workerd)의 기본 메모리 한도는 Isolate당 128MB이며 이는 번들 크기와 동시 요청 메모리를 합산한 값이다. Monaco/Shiki 같은 구문 강조기, TypeScript 컴파일러, PDF/캔버스 렌더링 라이브러리가 SSR 번들에 포함되지 않도록 빌드 분석기(vite-bundle-visualizer등)로 서버 번들을 반드시 별도 점검한다.
- 정적 프리렌더링(
prerender)과 동적 SSR 라우트의 명확한 분리: 가장 빠른 콜드 스타트는 워커를 아예 깨우지 않는 것이다. 랜딩 페이지나 문서처럼 요청마다 결과가 바뀌지 않는 라우트는@tanstack/react-start의prerender: { enabled: true }를 켜서 정적 자산으로 바로 응답하게 구성한다.
- 코드 배포와 시크릿(환경변수) 라이프사이클 분리: 멀티테넌트 환경이나 Workers for Platforms를 설계할 때 시크릿을 빌드 산출물에 하드코딩하지 말고 런타임 바인딩으로 주입해, 키 교체 시 재빌드 없이 워커 인스턴스만 교체되도록 설계한다.
참고 자료
- TanStack Start on Workers: Server-rendering apps an AI just wrote (Cloudflare Connect 2026) — Cloudflare Developers YouTube 공식 영상 (October 24, 2026 게시, November 2, 2026 확인)
- TanStack Start · Cloudflare Workers 공식 프레임워크 가이드 (November 2, 2026 확인)
- How Workers for Platforms works · Cloudflare for Platforms 공식 문서 (November 2, 2026 확인)
- Workers Limits (128 MB Memory per Isolate) · Cloudflare Workers 공식 문서 (November 2, 2026 확인)
- Server Functions (
createServerFn) · TanStack Start 공식 문서 (November 2, 2026 확인)