Cloudflare 오류 1102 리소스 한도 초과
Cloudflare 오류 1102는 Worker가 CPU·메모리(128MB) 한도를 넘긴 것으로 크래시가 아닙니다. 1101·1027과 구분, 무료 즉시 진단.
내 도메인에 이 문제가 있는지 지금 확인
무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.
Problem
Cloudflare Worker가 서빙하는 페이지가 Error 1102: Worker exceeded resource limits를 반환합니다. Worker는 돌았고 — 네트워크 장애도 던져진 예외도 아닙니다 — 단일 호출이 요금제가 허용하는 것보다 많은 CPU 시간이나 메모리를 썼고, 런타임이 멈춘 것입니다.
Symptoms
- Cloudflare 오류 페이지에 1101(예외)·1027(일일 한도)·520–526 오리진 오류가 아니라 1102 “Worker exceeded resource limits”가 표시됩니다.
- HTTP 진단이 그 URL에 Cloudflare 1102 페이지를 반환하고, 어느 네트워크에서든 재현됩니다.
- 무거운 입력에서 실패합니다 — 큰 요청 본문, 큰 JSON 페이로드, 렌더링할 긴 목록 — 같은 경로의 작은 요청은 성공하는데요.
- 무거운 작업이 isolate 시작 중 글로벌 스코프에서 돌면, 배포 직후 첫 요청(콜드 스타트)에서 실패하고 그 뒤엔 됩니다.
- 아무 데도 스택 트레이스가 없습니다. 아무것도 던지지 않았으니까요.
What 1102 Actually Means
Worker는 호출마다 엄격한 리소스 예산을 받고, 1102는 런타임이 그걸 집행하는 것입니다. 별개의 예산이 두 개 있고, 해결은 어느 쪽을 넘겼느냐에 달렸습니다.
CPU 시간. 코드를 실행하는 시간입니다 — 루프, JSON.parse, 암호화, 정규식, 문자열 조립. 결정적으로 네트워크를 기다리는 시간은 포함되지 않습니다: 느린 업스트림으로의 fetch()는 벽시계로 2초가 걸려도 CPU는 거의 안 씁니다. Free 요금제는 CPU를 요청당 10ms로 제한합니다. 작고, 가장 흔한 1102 방아쇠입니다: 큰 JSON 본문 파싱, 무한 루프, 무거운 템플릿이 데이터가 가장 많은 바로 그 요청에서 Free Worker를 10ms 너머로 넘깁니다. Paid 요금제는 기본 30초이고 진짜 CPU 바운드 작업엔 5분까지 올릴 수 있습니다.
메모리. 각 isolate는 Free·Paid 모두 128MB를 받습니다. 큰 요청·응답 본문을 메모리에 버퍼링하거나, 큰 객체를 글로벌 스코프에 쥐고 있거나, 계속 커지는 배열에 행을 쌓으면 넘어갑니다. isolate가 128MB를 넘으면 Cloudflare는 진행 중 요청을 끝내게 두고 새 isolate를 띄웁니다. 지속적으로 넘기면 엣지 안정을 위해 들어오는 요청이 1102로 드롭됩니다.
1102가 1101로 오진되는 이유는 둘 다 Worker 경로 위에 Cloudflare 오류 페이지로 렌더링되기 때문입니다. 하지만 1101엔 스택 트레이스가 있고 1102엔 없습니다 — 아무것도 던지지 않았고, 코드는 동작하고 있었으며, 그저 비용이 너무 컸습니다. 1102에서 예외를 찾아 헤매면 못 찾습니다. 버그는 크래시가 아니라 뜨거운 루프거나 뚱뚱한 할당이니까요.
Top 3 Causes
- Free의 10ms 예산 위 뜨거운 코드 경로 - Worker가 큰 JSON 본문을 파싱하거나, 크기가 입력에 비례하는 루프를 돌거나, 요청에 동기 암호화·압축을 합니다. 작은 입력은 10ms 아래, 큰 입력은 넘어갑니다. 1102가 전면 장애가 아니라 입력 의존적인 이유입니다 — 같은 경로가 페이로드 크기에 따라 되고 안 됩니다.
- 큰 본문을 메모리에 버퍼링 - 요청·응답 본문을 스트리밍하지 않고 문자열·배열로 통째 읽습니다. 큰 업로드 하나나 큰 업스트림 응답이 isolate를 128MB 너머로 밉니다. 거대한 것에
await response.text()를 하는 대신 본문을 스트리밍으로 흘려보내는 게 해결입니다. - 글로벌 스코프의 무거운 작업(콜드 스타트 1102) - 모듈 최상위의 비싼 초기화 — 큰 룩업 테이블 생성, 번들된 데이터셋 파싱, 무거운 라이브러리 import — 가 isolate 시작 중 돌며 CPU에 계산됩니다. 새 isolate를 데우는 첫 요청에서 1102가 나고, 그 뒤 “신기하게” 됩니다. 그 작업을 지연 초기화 뒤로 옮기거나 빌드 타임에 미리 계산하세요.
Diagnose with DechoNet
- HTTP 진단으로 1102가 네트워크 밖에서 실제로 재현되는지, 그리고 요청 크기와 상관관계가 있는지 확인하세요 — 실패 경로를 작은 페이로드와 큰 페이로드로 각각 쏴 보세요. 작은 건 성공하고 큰 건 1102면, 정상 상태 장애가 아니라 입력에 묶인 CPU·메모리 스케일링 문제입니다.
- DNS 진단으로 그 호스트명이 실제로 Cloudflare를 통해 프록시(오렌지 구름)되어 Worker가 경로에 있기라도 한지 확인하세요. 회색 구름 레코드는 Worker를 아예 건너뛰어 1102를 배제합니다.
Resolution Checklist
- 메시지가 “threw exception”(1101)·“daily request limit exceeded”(1027)가 아니라 “exceeded resource limits”인지 확인하세요. 셋의 해결은 무관합니다.
- Workers Logs(또는
wrangler tail)에서 호출당 CPU 시간을 읽으세요. CPU 시간이 호출 로그에 표시됩니다 — 그걸 튀게 하는 경로·입력 형태를 찾으세요. - Free이고 CPU 바운드라면, 뜨거운 경로를 최적화(루프 반복 줄이기, 더 싼 파싱, 계산값 캐시, 무거운 연산 오프로드)하거나 Paid로 옮겨 CPU 한도를 올리세요.
- 메모리는 큰 본문 버퍼링을 멈추세요 — 요청·응답을 통째 읽지 말고 스트리밍으로 흘리고, 큰 객체를 글로벌 스코프에서 빼고, 무한정 커지는 배열을 쌓지 마세요.
- 콜드 스타트 1102는 비싼 최상위 초기화를 지연 초기화 뒤로 옮기거나 빌드 타임에 미리 계산해 isolate 시작 중 돌지 않게 하세요.
- 재배포하고 작은 입력·큰 입력 둘 다로 HTTP 진단을 다시 돌려 한도에 더는 닿지 않는지 확인하세요.
When to Escalate
- 로그상 CPU 시간과 메모리 둘 다 예산 안에 넉넉한데도 요청이 계속 1102면, 오류 페이지의 Ray ID를 캡처해 Cloudflare 티켓을 여세요 — 런타임 쪽 측정 문제는 드물지만, Ray ID가 그 정확한 호출을 추적하게 해줍니다.
- 비용이 번들된 서드파티 라이브러리(무거운 파서, 엣지 런타임용이 아닌 암호화·이미지 라이브러리) 안으로 이어진다면, 그 패키지에 에스컬레이션하거나 교체하세요 — 일부 라이브러리는 서버급 CPU·메모리를 가정해 10ms / 128MB 봉투에 절대 안 들어갑니다.
관련 도구
관련 가이드
가이드 공유